React Hook:将数据从子组件发送到父组件

Posted

技术标签:

【中文标题】React Hook:将数据从子组件发送到父组件【英文标题】:React Hook : Send data from child to parent component 【发布时间】:2019-09-07 15:52:06 【问题描述】:

我正在寻找将数据从子组件传递给其父组件的最简单解决方案。

我听说过使用 Context、传递槽属性或更新 props,但我不知道哪个是最好的解决方案。

我正在构建一个管理界面,其中一个 PageComponent 包含一个 ChildComponent 和一个表格,我可以在其中选择多行。我想将我在 ChildComponent 中选择的行号发送给我的父 PageComponent。

类似的东西:

页面组件:

<div className="App">
  <EnhancedTable />         
  <h2>count 0</h2>
  (count should be updated from child)
</div>

子组件:

 const EnhancedTable = () => 
     const [count, setCount] = useState(0);
     return (
       <button onClick=() => setCount(count + 1)>
          Click me count
       </button>
     )
  ;

我确定这是一件非常简单的事情,我不想为此使用 redux。

【问题讨论】:

如何在PageComponent 上使用钩子并将其发送(countsetCount 通过道具发送到EnhancedTable 组件? 【参考方案1】:

我必须在 键入脚本 中执行此操作。面向对象方面需要开发者在继承自parent后将此回调方法作为一个字段添加到接口中,此prop的类型为Function。我觉得这很酷!

【讨论】:

【参考方案2】:

您可以在父组件中创建一个方法,将其传递给子组件,并在每次子组件的状态发生变化时从 props 调用它,从而将状态保留在子组件中。

    const EnhancedTable = ( parentCallback ) => 
        const [count, setCount] = useState(0);
        
        return (
            <button onClick=() => 
                const newValue = count + 1;
                setCount(newValue);
                parentCallback(newValue);
            >
                 Click me count
            </button>
        )
    ;

    class PageComponent extends React.Component  
        callback = (count) => 
            // do something with value in parent component, like save to state
        

        render() 
            return (
                <div className="App">
                    <EnhancedTable parentCallback=this.callback />         
                    <h2>count 0</h2>
                    (count should be updated from child)
                </div>
            )
        
    

【讨论】:

但现在this.callback 会触发不必要的重新渲染吗? @ecoe 当然可以,这取决于回调的确切作用。调用一些外部函数/调度动作应该是相对安全的,设置父级的状态——不是那么多。绝对这不是最干净的代码,所以如果可能的话,应该使用其他答案的方法。【参考方案3】:

我不得不处理一个类似的问题,并找到了另一种方法,使用一个对象来引用不同函数之间的状态,并且在同一个文件中。

import React,  useState  from "react";

let myState = ;

const GrandParent = () => 
  const [name, setName] = useState("i'm Grand Parent");
  myState.name=name;
  myState.setName=setName;
  return (
    <>
      <div>name</div>
      <Parent />
    </>
  );
;
export default GrandParent;

const Parent = () => 
  return (
    <>
      <button onClick=() => myState.setName("i'm from Parent")>
        from Parent
      </button>
      <Child />
    </>
  );
;

const Child = () => 
  return (
    <>
      <button onClick=() => myState.setName("i'm from Child")>
        from Child
      </button>
    </>
  );
;

【讨论】:

我真的不确定这是否是使用 useState 的正确方法。我建议密切关注官方文档 (reactjs.org/docs/hooks-state.html)。在您上面的答案中,您不需要“myState”,您可以只使用 useState 中的 name 和 setName 变量。试想一下,如果您想获得一个变量值,即“名称”,请使用第一个变量。如果要设置变量,请使用第二个变量,即 setName。公平竞争,很好地尝试提出自己的解决方案,但有时会以一团糟而告终。坚持最佳做法和官方文档。【参考方案4】:

为了让事情变得超级简单,您实际上可以将状态设置器共享给子级,现在他们可以访问设置其父级的状态。

示例: 假设有以下 4 个组件,

function App() 
  return (
    <div className="App">
      <GrandParent />
    </div>
  );


const GrandParent = () => 
  const [name, setName] = useState("i'm Grand Parent");
  return (
    <>
      <div>name</div>
      <Parent setName=setName />
    </>
  );
;

const Parent = params => 
  return (
    <>
      <button onClick=() => params.setName("i'm from Parent")>
        from Parent
      </button>
      <Child setName=params.setName />
    </>
  );
;

const Child = params => 
  return (
    <>
      <button onClick=() => params.setName("i'm from Child")>
        from Child
      </button>
    </>
  );
;

因此,祖父组件具有实际状态,并且通过将 setter 方法 (setName) 共享给父子组件,它们可以访问更改祖父组件的状态。

您可以在下面的沙箱中找到工作代码, https://codesandbox.io/embed/async-fire-kl197

【讨论】:

请提供链接中的基本详细信息,因为链接将来可能会过期。 感谢您的帮助。【参考方案5】:

针对这些情况的常用技术是将lift the state up 传递给需要使用状态的所有组件的第一个共同祖先(即本例中的PageComponent)并将状态和状态更改函数传递给子组件作为道具。

示例

const  useState  = React;

function PageComponent() 
  const [count, setCount] = useState(0);
  const increment = () => 
    setCount(count + 1)
  

  return (
    <div className="App">
      <ChildComponent onClick=increment count=count />         
      <h2>count count</h2>
      (count should be updated from child)
    </div>
  );


const ChildComponent = ( onClick, count ) => 
  return (
    <button onClick=onClick>
       Click me count
    </button>
  )
;

ReactDOM.render(<PageComponent />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="root"></div>

【讨论】:

是的,但是我需要将增量函数放在 ChildComponent 中。然后用结果更新父级。 感谢您将我从 forwardRef 的恐惧中拯救出来。它适用于我的项目。 问题是如果我有 const increment (value) => console.log(value) -> real value I've got from child c setState(value) console.log(state) - > undefined 但在第二次 callbackCall 之后,我得到了 prev 状态值。如何解决这个问题? 非常感谢。这真的帮助了我

以上是关于React Hook:将数据从子组件发送到父组件的主要内容,如果未能解决你的问题,请参考以下文章

React Hooks - 如何将道具从子组件传递到父组件?

在尝试将数据从子组件传递到父组件时,我收到一个错误 props.onSubmitForm is not a function in react

如何将变量的值从子组件发送到父组件?

如何在不调用事件的情况下将数据从子级发送到父级(vue 2)

如何在反应中将数组从子组件发送到父组件?

如何将数据从子组件传递到父组件[Angular]