【问题标题】:Set a child array state object from props value从 props 值设置子数组状态对象
【发布时间】:2019-04-09 16:41:10
【问题描述】:

我正在使用钩子创建一个反应应用程序,但我的代码出现了一个奇怪的行为,我不打算把我的所有代码都放在这里,但我会给你一个例子。

const Child = props => {
   const {data} = props;
   const [myData, setMyData] = useState(data);

  const items => myData.map( r => <li> r </li> );

   return ( <ul> { items } </ul> );
}

const Parent = () => {

   return (<div> 
             <Child data={ [1, 2, 3] } 
           </div> );
}

我正在更改父组件发送给子组件的数组。 当我向数组中添加一个新元素时,子组件会重新渲染,因此 MyData 等于数组(这是有道理的,因为子组件是通过道具更改重新渲染的)。 如果我从数组中删除一个元素,子组件会重新渲染,但 myData 不会更改,并且我从数组中删除的元素仍然存在于 myData 中。

为什么当我将元素添加到数组时 useState 将数组设置为 myData 但是当我删除元素时它似乎不起作用,即使子组件被重新渲染。

我知道这看起来有点笨,你可以问我,为什么你不只在 Child 组件上使用 props 值而不是 state 值,那么想法是在 Child 组件上有一个搜索控件所以我可以对 MyData 而不是 props 值进行某种搜索(但也许还有另一种方法)。

【问题讨论】:

  • 你能把所有相关代码贴在这里吗?

标签: javascript reactjs react-hooks


【解决方案1】:

我认为问题在于你如何使用道具。

Child 渲染时,它会从Parent 获得props.data。然后它将data 复制到其组件状态作为变量myData

从这里开始,对props 的更改可以触发Child 重新渲染,但myData 不会通过useState 再次重新定义。这种情况只会发生一次。

如果您正在编写进行热重载的代码(您保存文件并在浏览器中重新加载应用程序),可能看起来像更改发送到 Child 的 props 会更新 myData,但这不会发生在生产环境。

我的建议:如果你要将 props 分叉为 Child 的状态,请将 props 视为初始值,而不是 Parent 可以更新的东西。

React 文档解释了为什么这是一种反模式:

问题在于它既没有必要(您可以直接使用this.props.color),而且会产生错误(对颜色属性的更新不会反映在状态中)。

仅当您有意忽略道具更新时才使用此模式。

React constructor docs

【讨论】:

  • 感谢您的建议,也感谢您的教训,我会改变这一点。
【解决方案2】:
useEffect(() => {
    setMyData(data)
},[data])

您的数据只会加载到状态一次。但是你可以通过useEffect处理父组件对数据的更改,useEffect会在数据更新时更新

有完整的代码

const Child = props => {
   const {data} = props;
   const [myData, setMyData] = useState(data);

    useEffect(() => {
        setMyData(data)
    },[data])

  const items => myData.map( r => <li> r </li> );

   return ( <ul> { items } </ul> );
}

const Parent = () => {

   return (<div> 
             <Child data={ [1, 2, 3] } 
           </div> );
}

你可以阅读React use effect

【讨论】:

    猜你喜欢
    • 2019-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-14
    • 1970-01-01
    • 2019-10-20
    • 1970-01-01
    相关资源
    最近更新 更多