【问题标题】:How is state encapsulation maintained by React when passing state as a prop to a child component?将状态作为道具传递给子组件时,React 如何维护状态封装?
【发布时间】:2018-11-05 13:21:55
【问题描述】:

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

thisthis 问题的回答中的演示演示了作为对象的 React 道具是通过引用传递的,在此转载:

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 中可以将 state 作为 prop 传递给子组件。鉴于对象/数组 props 是通过引用传递的,React 如何维护状态封装?

子组件是否在本地复制传递给它的道具?因此,子组件不关心 prop 的来源是 state(即避免在传递给子组件的 prop 中反映父组件级别的状态更改的风险)。

【问题讨论】:

  • “父组件级别的状态变化反映在传递给子组件的道具中”不是期望的行为吗?通过setState 改变状态。直接的 state/prop 突变在 React 中是一个很大的禁忌。
  • props 是不可变的。

标签: javascript reactjs


【解决方案1】:

对象本身永远不会被传递,而是对对象的引用(最终隐式创建)。引用是按值传递的,如下面的 sn-p 所示。

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

【讨论】:

  • 澄清一下,我的问题实际上是关于 JS 中更广泛的数据封装,而不是“反应”问题本身,因为所有函数都通过引用传递对象。
  • React 数据封装方法与 vanilla JS 的不同之处在于它提供了一种数据结构,该数据结构赋予非原始值(即 props)不变性。
猜你喜欢
  • 2017-04-30
  • 1970-01-01
  • 1970-01-01
  • 2020-10-08
  • 2019-02-20
  • 1970-01-01
  • 2017-11-19
  • 2019-01-20
  • 2022-01-18
相关资源
最近更新 更多