React 从父组件收集有关某些事件的子组件数据

ksh*_*ksh 5 reactjs

在反应中,最佳实践是数据从父级流向子级,事件将从子级传递到父级。

如何避免此 UI 的反模式?

在此 UI 中,我们有一个父组件,其中包含 2 个带有表单的子组件。现在,当用户单击父组件中的提交按钮时,我们必须从子组件收集数据。

可能的解决方案(不好的解决方案|反模式):

  1. 从子级传递引用并从父级触发子方法来收集数据(从父级访问子方法不是一个好主意)
 <Parent>
    onFormData(data) {
     //here collect data from child
    }

    onSubmit() {
      //Trigger a method onData in child
      aRef.collectData()
    }

    <child-A ref={aRef} onData={onFormData}></Child-A>
    <Child-B ref={bRef} onData={onFormData}></Child-B>
    
    <button onClick={onSubmit}>Submit</Submit> 
</Parent>
Run Code Online (Sandbox Code Playgroud)
  1. 将道具绑定到子项,在提交时单击将道具的值更改为虚拟值。在 useEffect 钩子中观察相同的道具(非常糟糕的解决方案)
 <Parent>
    onFormData(data) {
     //here collect data from child
    }

    onSubmit() {
      //update randomValue, which will be observed in useEffect that calls onData method from child
      randomValue = Math.random();
    }

    <child-A triggerSubmit={randomValue} onData={onFormData}></Child-A>
    <Child-B triggerSubmit={randomValue} onData={onFormData}></Child-B>
    
    <button onClick={onSubmit}>Submit</Submit> 
</Parent>
Run Code Online (Sandbox Code Playgroud)

还有其他最好的方法来处理这些情况吗?如何避免此 UI 的反模式?

yai*_*iks 2

我通常做的是将状态“提升”给父母。这意味着我不会破坏自然的 React 流程,即将 props 从父级传递给子级。按照您的示例,我会将所有逻辑放在父级中(提交函数、表单状态等)

Const Parent = () => {
  const [formData, setFormData] = useState({})

  const onSubmitForm = () => {
      // send formData to somewhere
  }

  return (
      <ChildrenForm onChange={setFormData} formData={formData} />
      <button onSubmit={() => onSubmitForm()}>my button</button>
  )
}
Run Code Online (Sandbox Code Playgroud)

现在,每次 ChildrenForm 中的输入发生更改时,我将使用onChangeChildren 内部的函数来更新。formData所以我的所有状态都将在父级中,我不需要担心必须将所有内容从子级传递到父级(正如您提到的反模式)