Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does passing an object via props to child react component, clone the original object or pass by reference?

If am to pass an object to a child component via the components props, does this object get cloned or does it simply pass a reference to the original object?

For example in my App.js I am importing a JSON object ENTRY_DATA. I am then passing that object via props to my child components (or in this case, routes). Am I saving on memory by doing this or would it be the same as if I was to import ENTRY_DATA on each component?

import React, { Component } from 'react';
import { withRouter, Route } from 'react-router-dom'
import ENTRY_DATA from './../../entry_data.json';


import Register from '../Register/Register';
import Categories from '../Categories/Categories';
import Category from '../Category/Category';
import Entry from '../Entry/Entry';

class App extends Component {

  render() {

    return (
      <div className="app" >

        <main>
          <Route exact path="/" component={Register} />
          <Route exact path='/categories' render={(props) => (
            <Categories {...props} categories={ENTRY_DATA} />
          )}/>
          <Route exact path='/categories/:category' render={(props) => (
            <Category {...props} categories={ENTRY_DATA} />
          )}/>
          <Route exact path='/categories/:category/:entry' render={(props) => (
            <Entry {...props} categories={ENTRY_DATA} />
          )}/>
        </main>

      </div>
    );
  }
}

export default withRouter(App);

If ENTRY_DATA is 5kb's, And I am passing it to 3 different components, does that mean I end up with 20kb's worth of ENTRY_DATA or do they all reference the one 5kb ENTRY_DATA?

like image 993
Stretch0 Avatar asked Jan 11 '18 15:01

Stretch0


3 Answers

In general, it depends on the data-type of said prop. Primitives, such as integers or Strings are passed down by their value, while Object data-types such as arrays are passed down by their reference.

So yes, Objects specifically are passed down by reference.


Demo:

In this demo we have two components, one parent and one child. The child takes two props, one that is the integer 1 and the other is an object with a: "foo".

After a short while, from the parent we change the integers value from 1 to 2 and the object from a: "foo" to a: "bar". After that, we log the values of these props from the child component.
Note: This is a stateless component, so we aren't using any kind of state. We are changing the values directly, so React won't ever "know" of this change! (ssh, don't tell React!)

The output is still 1 for the integer (didn't change - passed by value), but a: "bar" for the object (changed! - passed by reference).

const Parent = () => { 
  let myInt = 1;
  let myObj = {a: "foo"};
  setTimeout(function(){
    myInt = 2;
    myObj.a = "bar";
  }, 500);
 
  return <Child myInt={myInt} myObj={myObj} />;
}

const Child = ({myInt, myObj}) => {
  setTimeout(function(){
    console.log(myInt);
    console.log(myObj);
  }, 1000);
  
  return (
    <div>
      <p>{myInt}</p>
      <p>{JSON.stringify(myObj)}</p>
    </div>
  );
}
 
ReactDOM.render(<Parent />, document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
like image 156
Chris Avatar answered Oct 12 '22 04:10

Chris


Props reference to objects, in fact you can pass methods with context. Mutating props is a very bad pratice discouraged by almost every linter, when you want to mutate data coming from props is better to deep clone prop and work on cloned data.

like image 20
Mosè Raguzzini Avatar answered Oct 12 '22 05:10

Mosè Raguzzini


Only a reference to the object is passed. Indeed, the transformation is pretty straightforward between jsx/tsx and plain old js/ts. This babel reference is a good example of this.

This means that any sort of object can potentially be sent - numbers, booleans, arrays, functions, plain old objects, DOM elements etc. It also means that if the object is mutable, it could be modified. But it should not.

like image 3
Horia Coman Avatar answered Oct 12 '22 06:10

Horia Coman