代码之家  ›  专栏  ›  技术社区  ›  Will

当将状态作为一个属性传递给子组件时,react如何维护状态封装?

  •  3
  • Will  · 技术社区  · 6 年前

    这个问题与react的实现细节有关,更具体地说,与状态封装有关。

    演示 this 回答 this 问题表明,对象的react props是通过引用传递的,在此处重现:

    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>

    可以在反应中将状态作为一个道具传递给子组件。假设对象/数组的属性是通过引用传递的,那么react如何维护状态封装呢?

    子组件是否本地复制传递给它的属性?因此,子组件不关心prop is state的起源(即,避免在传递给子组件的prop中反映父组件级别的状态变化风险)。

    1 回复  |  直到 6 年前
        1
  •  3
  •   Attersson    6 年前

    对象本身不会被传递,而是引用对象(最终隐式创建)。引用是按值传递的,如下面的代码段所示。

    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);

    打电话 someFunc({myKey:"myVal"}) 并不意味着将对象作为参数传递,而是隐式引用其他未引用的对象(否则,该对象将排队等待垃圾收集)。

    props 是不变的。

    引用存储一个javascript类型的变量的地址,包括对象。由于您将引用的一个(浅)副本作为参数传递,这意味着引用仍然“引用”到同一个内存。即使传递的引用是副本。