3

This question relates to an implementation detail of React, more specifically, to state encapsulation.

The demo in this answer to this question demonstrates that React props that are objects are passed by reference, reproduced here:

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>

It is possible in React to pass state as a prop to a child component. Given that objects/arrays props are passed by reference, how is state encapsulation maintained by React?

Does the child component locally copy the props that are passed to it? Thereby the child component does not care about the origin of the prop is state (i.e. avoids the risk of state changing at the level of parent component being reflected in the prop that is passed to the child component).

Will
  • 521
  • 1
  • 6
  • 18
  • 1
    "state changing at the level of parent component being reflected in the prop that is passed to the child component" isn't that the desired behavior? State changing via `setState` that is. Direct state/prop mutation is a big no in React. – Roy Wang May 26 '18 at 09:16
  • `props` is immutable. – Carr May 26 '18 at 09:21

1 Answers1

3

Objects are never passed themselves, but references to Objects (eventually implicitly created). The reference is passed by value as the snippet below illustrates.

console.log("Initial Object a:");
a = {helloKey: "helloVal"};
console.log(a);
function useObj(obj){
  console.log("Reference a copied to obj inside function:");
  console.log(obj);
  obj = {byeKey:"byeVal"};
  console.log("obj edited:");
  console.log(obj);
}

useObj(a);
console.log("a is untouched:");
console.log(a);

Calling someFunc({myKey:"myVal"}) does not mean passing an Object as argument, but an implicit reference to an otherwise unreferenced Object (which would, otherwise, be queued for garbage collection.

props is immutable.

A reference stores the address of a variable of one of the Javascript types, including Objects. Since you pass a (shallow) copy of a reference as argument, this means references still "reference" to the same memory. Even though the passed reference is a copy.

Attersson
  • 4,755
  • 1
  • 15
  • 29
  • To clarify, my question is really about data encapsulation in JS more broadly rather than a 'React' question per-se, given that all functions pass objects by reference. – Will May 26 '18 at 10:14
  • What is different about React approach to data encapsulation vis-à-vis vanilla JS is the way it makes available a data structure that confers immutability to non-primitive values i.e. props. – Will May 26 '18 at 10:34