简体   繁体   English

将 useState 设置器传递给孩子以更新父母 state 是否是正确的方法?

[英]Is it a correct approach to pass useState setter to a child for updating parents state?

We can pass a callback to a child as props and update the state but I was just wondering can I pass useState setter to the child and call it directly in child to update parents state?我们可以将回调作为道具传递给孩子并更新 state 但我只是想知道我可以将 useState 设置器传递给孩子并直接在孩子中调用它来更新父母 state?

Something like:就像是:

 function Parent(){ const [data, setData] = useState(); return( <Child setData={setData}/> ); } function Child({setData}){ useEffect(()=>{ setData('new data'); //Calling setter here to update }, []) }

Yes, you can do that.是的,你可以这么做。 In fact, it is good practice to do that.事实上,这样做是个好习惯。 To avoid unnecessary re-renders and infinite loops, either include setData in the dependency array of the Child's useEffect or wrap the data in a useCallback in the Parent component.为了避免不必要的重新渲染和无限循环,要么在 Child 的useEffect的依赖数组中包含setData ,要么将data包装在 Parent 组件的useCallback中。 Also, it is recommended to initialise the data to some initial value when using useState .此外,建议在使用useState时将数据初始化为某个初始值。 In your case, I would initialise it to null -> const [data, setData] = useState(null)在您的情况下,我会将其初始化为null -> const [data, setData] = useState(null)

Example with the dependency array:依赖数组的示例:


function Child({ setData }) {
  useEffect(() => {
    setData("new data"); //Calling setter here to update
  }, [setData]);

  return (...);
}

If you want to pass it to a child that is multiple levels deep, I would suggest using Context.如果你想将它传递给一个多层次的孩子,我建议使用 Context. With context, you can then use the useState in any child and you don't need to pass it as props throughout all of the children between the Parent and the Child that you want to use it in.有了上下文,您就可以在任何孩子中使用useState并且您不需要将它作为道具传递给您想要使用它的ParentChild之间的所有孩子。

Example with the Context:上下文示例:


// Step 1. Create context
const MyContext = React.createContext();

// Step 2. Create a custom hook that will return Context
// This will allow you to use the context in any number of children more easily.
// And it will also make sure that it is only used within Parent component
const useData = () => {
  const context = React.useContext(MyContext);

  if (!context) {
    throw new Error("useData must be used within a <Parent />");
  }

  return context;
};

function Parent() {
  const [data, setData] = useState(null);
  const value = [data, setData];

  // Step 3. Use Context Provider and pass the value of the props that
  // need to be used by any children down the tree
  return (
    <MyContext.Provider value={value}>
      <Child />
    </MyContext.Provider>
  );
}

function Child() {
  return <ChildTwo />;
}

function ChildTwo() {
  // Step 4. Extract the prop from the Context that you need using custom hook
  const [data, setData] = useData();

  useEffect(() => {
    setData("new data"); //Calling setter here to update
  }, [setData]);

  return (...);
}

Yes, that is perfectly ok.是的,这完全没问题。 You can also utilize useContext() (global variables/functions) and even consider using an HOC in the future if you'll be working with many hooks.您还可以使用 useContext() (全局变量/函数),如果您将使用许多钩子,甚至可以考虑在将来使用 HOC。 Then you can centralize all of the hooks to one component and re-use them throughout your application.然后,您可以将所有挂钩集中到一个组件中,并在整个应用程序中重复使用它们。

For an HOC some common use cases from my past projects are:对于 HOC,我过去项目中的一些常见用例是:

  • Errors错误
  • Validation验证
  • Authentication验证

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

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