繁体   English   中英

如何通过引用而不是值传递父级的反应道具/状态?

How to pass react props/state of parent by reference, not value?

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

我正在使用反应钩子并尝试将父级的状态传递给多个组件。 问题是当我想要传递状态的组件本身是状态的一部分时。 我创建了一个示例来说明我的问题,我有一个按钮可以增加计数器并将另一个按钮附加到列表中。 我想看到显示的按钮列表,并且都从状态中读取相同的计数器值,但是当我附加一个新按钮时,计数器的值总是在创建按钮时按值传递,并且它不更新。 在我的项目(此处未显示)中,我通过将函数传递给组件以检索父状态并手动更新所有组件来规避了这个问题,但是通过这样做,我觉得我真的打破了不必要的反应设计原则复杂的代码会导致更多的问题。

我的按钮示例:

import React from 'react'

function Button(props){
  return <button onClick={()=>{
    // increment the counter
    props.setcounter(cur=>cur+1);

    // add another button
    // these props are not passed by reference: how do I pass these by reference?
    props.setitems(items=>items.concat(<tr><td><Button {...props}/></td></tr>))
    }}>
    {props.counter}
    </button>
}
function App() {
  const [items,setitems]=React.useState([]);
  const [counter,setcounter]=React.useState(0);
  return (
    <div className="App">
      <table>
    <th><td>Button with props passed by reference:</td></th>
    <tr><td><Button counter={counter} setcounter={setcounter} setitems={setitems} /></td></tr>
      </table>
      <table>
       <th><td>Button with props passed by value:</td></th>
    {items}
      </table>
    </div>
  );
}

export default App;

 function Button(props){ return <button onClick={()=>{ // increment the counter props.setcounter(cur=>cur+1); // add another button // these props are not passed by reference: how do I pass these by reference? props.setitems(items=>items.concat(<tr><td><Button {...props}/></td></tr>)) }}> {props.counter} </button> } function App() { const [items,setitems]=React.useState([]); const [counter,setcounter]=React.useState(0); return ( <div className="App"> <table> <th><td>Button with props passed by reference:</td></th> <tr><td><Button counter={counter} setcounter={setcounter} setitems={setitems} /></td></tr> </table> <table> <th><td>Button with props passed by value:</td></th> {items} </table> </div> ); } ReactDOM.render( <App />, document.getElementById("root") );
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script> <div id="root"></div>

它的作用:

在此处输入图片说明

当我多次单击顶部按钮时,它每次都会使用计数器的当前值创建一个新按钮,但它不是通过引用传递的,因此不会在计数器值更新时更新。

我想要它做什么:

所有新创建的按钮都应该具有相同的计数器值,因为我希望它通过引用传递,而不是我单击按钮时的值。 当我单击任何按钮时,应该创建一个新按钮,并且应该更新每个按钮上的值以匹配新的计数器值。

1 个回复

问题是当我想要传递状态的组件本身是状态的一部分时。

这确实是问题所在,正如您发现的那样,React 中的反模式会产生陈旧的值。 理想情况下,您不应该将任何组件保持在 state 中,如果您这样做了,它们必须是完全纯净的(即在它们的生命周期中不易于接收新的 props)。

当你调用这个 state setter 时实际发生了什么:

props.setitems(items=>items.concat(<tr><td><Button {...props}/></td></tr>))

这是,假设这是第一次被调用:

<Button counter={0} ... />

该按钮的计数器不仅只有值0 ,而且它创建的任何按钮都将具有相同的值。 你所说的在 React 上下文中实际上没有意义,因为重点是为了触发重新渲染和效果而打破引用(以及更普遍的严格相等)。

我们希望保持我们的状态不可变,这意味着重新创建它的任何部分,这些部分在每次渲染时都会发生变化。 对于您正在做的工作,每当您创建一个新的items时,您都必须通过循环与items长度一样多的次数来重新创建整个按钮存储。

您应该考虑的方式是如何数据派生 UI,而不是将其存储数据:

 function Button(props){ return <button onClick={()=>{ props.setcounter(cur=>cur+1); props.setitems(items=> [...items, 1]) }}> {props.counter} </button> } function App() { const [items,setitems]=React.useState([1]); const [counter,setcounter]=React.useState(0); return ( <div className="App"> {items.map(() => <Button counter={counter} setcounter={setcounter} setitems={setitems}/>)} </div> ); } ReactDOM.render( <App />, document.getElementById("root") );
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script> <div id="root"></div>

2 如何在 React 中将状态传递给 props

我是 React 的新手,并试图制作一个项目,该项目使用盘子.js 文件作为 MenuComponent.js 中的参数以在 DishdetailComponent.js 中使用。 但是,当我编译时,它没有任何错误或警告。 在我的代码中,MenuComponent.js 是我的父级,而 Dishde ...

5 如何在 React 中将 props props 从 Parent 传递给 this.props.children

我在尝试将道具传递给this.props.children遇到困难。 我知道有一些类似的帖子,但是,我相信我已经尝试了大多数公认的解决方案,但它仍然没有表现和预期。 所以,我想我错过了一些重要的东西。 总体思路是这样的:我有一个&lt;NavBar&gt;组件,我想将它包裹在我的页面上,如下所示。 ...

8 如何将道具传递到React组件中的状态

我已经创建了这个组件,该组件使用对象数组并填充位于状态中的结果。 这是一个轮播,根据存在的数据显示箭头,所以这就是我要通过状态执行此操作的原因。 (我包括了整个代码,所以您可以看到)。 现在,我希望将此轮播用于不同的页面,并希望动态地从每个页面提取数据。 我知道我可以通过道具来做到这 ...

9 将更新的父状态传递给子道具 React.js

我的父组件中有两个子组件,并设置了路由。 Child1 组件的按钮更新父组件的状态,我想将该状态的更新版本作为道具传递给 child2 组件。 问题是,虽然状态在父组件中明显更新(我检查了它),但它没有传递给 child2 组件(而是传递了旧版本的状态)。 我认为这是因为getdData函数(在父 ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2022 STACKOOM.COM