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

时间:2020-03-19 22:42:55

标签: arrays reactjs object react-hooks parent-child

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

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.
      }}
  )
}

1 个答案:

答案 0 :(得分:4)

也许您不知道它是什么,而您却取消了状态:基本上,不是将状态保留在Child组件中,而是将其保留在Parent中。
这是一个使用过的模式,没有什么错:您只是错过了一个让孩子们更新Parent状态的handle函数:为此,您需要在{ handleChange组件,然后将其作为道具传递给每个Parent

看看下面的代码示例:

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} /> ); } 用于name,可以对所有input元素仅使用一个处理函数。在函数内部,在这种情况下为input,您可以使用onInputChange;
  • 请注意,我在您的e.target.name中添加了一个空数组依赖项:没有它,useEffect将在每次渲染时都运行。我想那不是你想要的。
    相反,我邀请您,您只想在挂载组件时才执行请求,而这可以通过n个空数组依赖来实现;