使用 React 钩子,我如何更新通过道具传递给孩子的对象?

Posted

技术标签:

【中文标题】使用 React 钩子,我如何更新通过道具传递给孩子的对象?【英文标题】:Using React hooks, how can I update an object that is being passed to a child via props? 【发布时间】:2020-07-01 02:44:47 【问题描述】:

父组件包含一个对象数组。 它映射数组并为每个对象返回一个子组件,并用该对象的信息填充它。 在每个子组件内部都有一个输入字段,我希望它允许用户更新对象,但我不知道如何去做。 在钩子、道具和对象不变性之间,我在概念上迷失了方向。 这是父组件的简化版本:

const Parent = () => 
  const [categories, setCategories] = useState([]);

  useEffect(()=>
    // makes an axios call and triggers setCategories() with the response
  

  return(
    categories.map((element, index) => 
      return(
        <Child
          key = index
          id = element.id
          firstName = element.firstName
          lastName = element.lastName
          setCategories = setCategories
    )
  )

这是子组件的简化版本:

const Child = (props) => 
  return(
    <h1>props.firstName</h1>
    <input
      defaultValue = props.lastName
      onChange=()=>
        // This is what I need help with.
        // I'm a new developer and I don't even know where to start.
        // I need this to update the object's lastName property in the parent's array.
      
  )

【问题讨论】:

请提供minimal reproducible example,但请注意,这不是教程服务。 忘记这个钩子,你知道如何以不可变的方式更新数组中的对象吗? @jonrsharpe 我刚刚更新了它。希望这会有所帮助。我是开发和 Stack Overflow 的新手,所以我仍然习惯于如何提出好的问题。 见meta.***.com/q/284236/3001761;如果您不知道从哪里开始,结构化教程可能是比 SO 问题更好的选择。 不,不要删除您的问题,这很好。如果你认为你知道如何更新数组,并且不可变地发布代码,那么我们可以看到你哪里出错了。如果您遇到错误,请发布该错误 【参考方案1】:

也许在不知情的情况下,您解除了状态:基本上,不是将状态保存在 Child 组件中,而是将其保存在 Parent 中。 这是一个使用过的模式,并没有错:你只是错过了一个句柄函数,它允许孩子更新Parent 的状态:为了做到这一点,你需要在Parent 组件上实现一个handleChange ,然后将其作为道具传递给每个Child

看看这个代码示例:

const Parent = () => 
    const [categories, setCategories] = useState([]);

    useEffect(() => 
        // Making your AXIOS request.
    , []);

    const handleChange = (index, property, value) => 
        const newCategories = [...categories];
        newCategories[index][property] = value;

        setCategories(newCategories);
    

    return categories.map((c, i) => 
        return (
            <Child
                key=i
                categoryIndex=i
                firstName=c.firstName
                lastName=c.lastName
                handleChange=handleChange />
        );
    );


const Child = (props) => 
    ...

    const onInputChange = (e) => 
        props.handleChange(props.categoryIndex, e.target.name, e.target.value);
    

    return (
        ...
        <input name='firstName' value=props.firstName onChange=onInputChange />
        <input name='lastName' value=props.lastName onChange=onInputChange />
    );

你可能不知道的几件事:

通过对input 使用属性name,您可以对所有input 元素仅使用一个处理函数。在函数内部,在本例中为 onInputChange,您可以使用 e.target.name 检索该信息; 请注意,我在useEffect 中添加了一个空数组依赖项:没有它,useEffect 将在每次渲染时运行。我不认为这是你想要的。 相反,我希望您仅在挂载组件时才执行请求,这可以通过 n 个空数组依赖项来实现;

【讨论】:

您真的抽出时间来给我一个简单、简洁、充分的回答我的问题。我无法告诉你我多么感激你这样做。太感谢了!刚刚将它添加到我的代码中并且它有效。更重要的是:我明白它为什么会起作用。再次感谢!

以上是关于使用 React 钩子,我如何更新通过道具传递给孩子的对象?的主要内容,如果未能解决你的问题,请参考以下文章

使用状态钩子在组件之间传递道具

React中传递道具和映射数据

如何使用 onClick 方法通过 react-router 传递道具

如何通过链接和路由传递道具/状态 - react.js

如何在反应钩子中创建一个新的 JSON 对象?

它们是使用包含更新的道具和先前状态的 useState 钩子来更新状态的功能形式吗?