Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/407.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何通过引用而不是值传递父级的react props/state?_Javascript_Reactjs - Fatal编程技术网

Javascript 如何通过引用而不是值传递父级的react props/state?

Javascript 如何通过引用而不是值传递父级的react props/state?,javascript,reactjs,Javascript,Reactjs,我正在使用react钩子并试图将父级的状态传递给多个组件。问题是当我想要传递状态的组件本身是状态的一部分时。我创建了一个例子来说明我的问题,我有一个按钮,它增加一个计数器,并在列表中附加另一个按钮。我希望看到显示的按钮列表以及所有从状态读取相同计数器值的按钮,但是当我附加一个新按钮时,计数器的值总是在创建按钮时按值传递,并且不会更新。在我的项目(此处未显示)中,我通过将函数传递给组件来检索父状态并手动更新所有组件,从而绕过了这个问题,但是通过这样做,我觉得我真的打破了react的设计原则,使用了

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

我的按钮示例:

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;

从“React”导入React
功能按钮(道具){
返回{
//递增计数器
道具设置计数器(cur=>cur+1);
//添加另一个按钮
//这些道具不是通过引用传递的:我如何通过引用传递这些道具?
props.setitems(items=>items.concat())
}}>
{props.counter}
}
函数App(){
const[items,setitems]=React.useState([]);
const[counter,setcounter]=React.useState(0);
返回(
通过引用传递道具的按钮:
按值传递道具的按钮:
{items}
);
}
导出默认应用程序;
功能按钮(道具){
返回{
//递增计数器
道具设置计数器(cur=>cur+1);
//添加另一个按钮
//这些道具不是通过引用传递的:我如何通过引用传递这些道具?
props.setitems(items=>items.concat())
}}>
{props.counter}
}
函数App(){
const[items,setitems]=React.useState([]);
const[counter,setcounter]=React.useState(0);
返回(
通过引用传递道具的按钮:
按值传递道具的按钮:
{items}
);
}
ReactDOM.render(
,
document.getElementById(“根”)
);

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

这确实是问题所在,正如您所发现的,React中的反模式会创建过时的值。理想情况下,您不应该让任何组件处于状态,如果您这样做,它们必须是完全纯净的(即,在其生命周期内不容易收到新道具)

当您调用此状态设置器时,实际发生了什么:

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


因此,如果我想了解它,您希望使用按钮更新将传递回应用程序组件的道具,但您也希望同时更新计数器以显示递增值的按钮。这就是我想要的,当前底部表格中按钮上的值未更新。只有新添加的按钮才能获取计数器的当前状态值,而其他按钮则没有更新。好吧。为什么不将实际按钮移动到应用程序组件。然后更新计数器并使用{[…数组(计数器+1)].map({counter})创建按钮组件
<Button counter={0} ... />