Javascript 如何在React函数组件中为setState创建指定的回调函数
这个问题可能与其他问题相似,但事实并非如此。我面临的问题有点棘手 在官方React文档中,它说Javascript 如何在React函数组件中为setState创建指定的回调函数,javascript,reactjs,Javascript,Reactjs,这个问题可能与其他问题相似,但事实并非如此。我面临的问题有点棘手 在官方React文档中,它说useffect可以作为setState中内联callBack函数的替代。要创建这样一个回调事件,我们需要在useffect函数上传递一个数组,并且只有在数组值发生任何变化时,useffect函数才会运行,从而创建一个回调函数 但是,假设在我的react函数组件中,我创建了一个状态,其中包含一个具有多个属性的对象 还有两个按钮,按钮1,按钮2。单击按钮1时,会触发设置状态功能,如下所示: 并调用回调函数
useffect
可以作为setState
中内联callBack
函数的替代。要创建这样一个回调
事件,我们需要在useffect
函数上传递一个数组
,并且只有在数组值发生任何变化时,useffect
函数才会运行,从而创建一个回调
函数
但是,假设在我的react函数组件中,我创建了一个状态
,其中包含一个具有多个属性的对象
还有两个按钮,按钮1
,按钮2
。单击按钮1
时,会触发设置状态
功能,如下所示:
并调用回调
函数,即:
当点击按钮2
时,它也会触发setState
。像这样:
setState({…state,姓名:“harry”,年龄:19})
与前一次一样,这次还发生了一个回调
函数,即:
这就是一切都变得一团糟的地方。单击按钮1
时,我希望
一个console.log
,上面写着“姓名、姓氏、年龄和父母姓名已更改”
,但我们得到的是:
表示单击按钮1
时触发了useffect
回调函数。这不是我想要的。这同样适用于按钮2
。之所以发生这种情况,是因为useffect
都有一个common数组值
如果它是一个基于React类的组件,我们将在setState
之后传递一个内联函数。但是在反应功能组件中,它变得复杂。这是现场演示
当我尝试将基于react类的组件转换为功能组件时,经常会出现这种情况。那么,我如何在React函数组件中创建一个特定的回调
函数,该函数仅在特定的设置状态
发生后运行?调用这两个useffect
是正确的。如果任何属性依赖于更改,则会触发useffect
在您的示例中,由于两个useffect
s都在侦听state.name
,因此如果此值更改,这两个都将触发
对于这种方法,您要问的是如何比较当前状态和新状态useRef
是一个很好的用例
由于您的所有状态都在一个对象中,因此您可以在一个useffect
hook中运行所有这些,并使用state
对象触发它:
const previousState=useRef(状态);
useffect(()=>{
if(previousState.current.name!==state.name){
控制台日志(“名称更改”);
}
如果(previousState.current.age!==状态.age){
控制台日志(“年龄更改”);
}
previousState.current={…state};//更新以前的状态
},[州];
我设计了比较,结果可能会变得一团糟。但您可以看到如何检查状态的哪些部分已更改,然后在此基础上运行条件行为。我认为问题正是您所期望的:
这就是一切都变得一团糟的地方。单击按钮1时,我
希望得到一个console.log,上面写着“姓名、姓氏、年龄和父母姓名已更改”,但我们得到的是:
“姓名、姓氏、年龄和父母姓名已更改”
“姓名和年龄已更改”
当然,这两种效果都会被触发,因为两种效果中都有state.name
作为deppendecy-您可以通过单击每个按钮来更改此键
尝试添加新按钮:
<button onClick={() => setState({ ...state, parent: state.parent === "live" ? "dead" : "live"})}>
toggle parent
</button>
setState({…state,parent:state.parent==“live”?“dead”:“live”})}>
切换父项
并且将看到唯一触发了独立性的state.parent
的效果
这是否回答了您的问题?根据您的目标,这里有两种可能的解决方案
当您在依赖项数组中订阅的任何值发生更改时,将触发useffect
挂钩。因此,如果我们想知道哪个值被更改了,我们可以为每个状态值添加一个单独的useffect
hook
useEffect(() => console.log('Name changed.'), [state.name])
useEffect(() => console.log('Last Name changed.'), [state.lastName])
useEffect(() => console.log('Age changed.'), [state.age])
useEffect(() => console.log('Parent changed.'), [state.parent])
钩子很好,但不是你描述的唯一方法,事实上也不总是最好的方法。有时,您可能希望专门在按下按钮时运行代码,如:
const onButton1Pressed = () => {
setState(prevState => ({
...prevState,
name: "steve",
lastName: "potter",
parent: "dead"
}))
console.log('Changed name, lastname, parent')
}
const onButton2Pressed = () => {
setState(prevState => ({
...prevState,
name: "harry",
age: 19
}))
console.log('Changed name, age')
}
useEffect(() => {
console.log("Name and age are changed")
}, [state.name, state.age])
"Name, last Name, age and parent name Changed"
"Name and age are changed"
<button onClick={() => setState({ ...state, parent: state.parent === "live" ? "dead" : "live"})}>
toggle parent
</button>
useEffect(() => console.log('Name changed.'), [state.name])
useEffect(() => console.log('Last Name changed.'), [state.lastName])
useEffect(() => console.log('Age changed.'), [state.age])
useEffect(() => console.log('Parent changed.'), [state.parent])
const onButton1Pressed = () => {
setState(prevState => ({
...prevState,
name: "steve",
lastName: "potter",
parent: "dead"
}))
console.log('Changed name, lastname, parent')
}
const onButton2Pressed = () => {
setState(prevState => ({
...prevState,
name: "harry",
age: 19
}))
console.log('Changed name, age')
}