【问题标题】:Is possible set state from parent and set state from children at same element?是否可以在同一元素中从父级设置状态和从子级设置状态?
【发布时间】:2021-01-16 01:59:09
【问题描述】:

我有一个组件,我需要更新父级的值(好的),但是如果用户更改输入的值(子级/功能性组件),我需要设置这个值而不传递给父级重新渲染孩子们。

看这个例子: https://codesandbox.io/s/boring-thunder-qvibf?file=/src/App.js

按照以下步骤操作:

  1. 为输入设置一些值并查看控制台日志
  2. 点击按钮,输入接收新值
  3. 再次更改输入值
  4. 单击按钮,为什么不能再次工作并设置值输入?

我需要独立的孩子(功能组件或类组件),有时我需要使用parent来设置children值,还要保持children改变自己的状态,这可能吗?

【问题讨论】:

  • 这是一个在父节点中保持状态并将控制权传递给子节点的示例:How can I pass state from page to component and back to page?
  • 嘿@pichard,谢谢回复,但在这个例子中,状态是由父级控制的,我需要保持由父级和子级控制,没有传递回调给父级重新渲染是可能的孩子们?谢谢。
  • 我首先要说的是,从 props 设置状态是一种反模式,最好在一个地方设置/处理状态。但是您的示例不起作用的原因是第一次单击按钮会更改 valueParent 并因此重新呈现,但是任何后续单击不会更改 valueParent 的值和所以不要触发渲染。 (如果您在 setValueParent() 调用中添加时间戳或其他新值,它会按预期工作)

标签: javascript reactjs react-native react-props


【解决方案1】:

您的示例不起作用的原因是,在第一次单击之后的任何按钮都不会更改父状态的值,因此不会触发渲染。

下面是一个简单的 sn-p,它通过在每次点击时添加一个唯一的计数器值来解决这个问题,以始终触发渲染,但您也可以将处理程序传递给子进程并清除父状态,或将其与子状态,等待下一个按钮点击。

我会说从 props 设置状态是一种反模式,会导致意外断开连接(正如问题所证明的那样);最好在一个地方设置/处理状态。

const App = () => {
  const [parentValue, setParentValue] = React.useState("");

  const clickCount = React.useRef(0);
  const parentValueHandler = () => {
    setParentValue(`New value from parent ${++clickCount.current}`);
  };

  return (
    <div className="App">
      <Child parentValue={parentValue} />
      <button onClick={parentValueHandler}>Change value to Parent</button>
    </div>
  )
}

const Child = ({ parentValue }) => {
  const [value, setValue] = React.useState(parentValue);

  React.useEffect(() => {
    setValue(parentValue);
  }, [parentValue]);

  return (
    <input
      type='text'
      name='child'
      value={value}
      onChange={(e) => setValue(e.target.value)}
    />
  );
}


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>

【讨论】:

    猜你喜欢
    • 2020-05-07
    • 1970-01-01
    • 2020-10-18
    • 1970-01-01
    • 1970-01-01
    • 2021-06-15
    • 2021-03-14
    • 2015-05-19
    • 1970-01-01
    相关资源
    最近更新 更多