我正在使用钩子创建一个React应用程序,但是我的代码出现了奇怪的行为,我不会将所有代码都放在这里,但是我会给你一个例子。
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> );
}
我正在更改父组件发送给子组件的数组。 当我向数组添加新元素时,Child组件重新渲染,因此MyData等于数组(这是有道理的,因为通过props change可以重新渲染Child组件)。 如果我从数组中删除一个元素,则将重新渲染Child组件,但myData不会更改,并且从数组中删除的元素仍在myData中。
为什么当我向数组添加元素时useState将该数组设置为myData,但是当我删除元素时,即使重新渲染Child组件,这似乎也不起作用。
我知道这似乎有点愚蠢,您可以问我,为什么不只在Child组件上使用props值而不是state值,好主意是在Child组件上有一个搜索控件,所以我可以对MyData进行某种搜索,而不是对props值进行搜索(但也许还有另一种方法)。
答案 0 :(得分:1)
我认为问题在于您如何使用道具。
渲染Child
时,它会从props.data
中获取Parent
。然后,它将data
复制为其组件状态,作为变量myData
。
从此处开始,对props
的更改可能会触发Child
重新呈现,但是不会通过myData
重新定义useState
。那只会发生一次。
如果您正在编写进行热重载的代码(保存文件,然后在浏览器中重载应用程序),则看起来好像更改了发送到Child
的道具会更新myData
,但是在生产环境中不会发生这种情况。
我的建议:如果您打算将道具分叉到Child
的状态,请将道具视为初始值,而不是Parent
可以更新的东西。
React文档解释了为什么这是反模式:
问题在于,这既不必要(您可以直接使用
this.props.color
),又会产生错误(对颜色道具的更新不会反映在状态中)。仅当您有意忽略道具更新时才使用此模式。
答案 1 :(得分:1)
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
的信息