React子组件useEffect不明原因触发多次:
有一个下拉控件会多次用到,于是想封装成一个单独的控件,下拉选项从服务端获取,获取逻辑我放在了useEffect里:
useEffect(() => {
console.log("Child useEffect");
setCustomers([
{value: 'all', label: t('poLineManagement.all')},
{value: 'one', label: 'One'},
{value: 'two', label: 'Two'},
{value: 'three', label: 'Three'},
]);
// 从服务端获取,目前暂时注释了,注释与否都不影响现象。
}, []);
const onValueChange = (event) =>{
console.log("onValueChange: " + event.target.value);
setCurrentCustomer(event.target.value);
if(props.onValueChange) {
props.onValueChange(event.target.value);
}
}
return (
<Select
value={currentCustomer}
variant="outlined"
color="primary"
fontSize="small"
className={classes.select1_3}
classes={{ select: classes.outlinedPadding }}
onChange={onValueChange}
>
{customers && customers.length > 0 && customers.map((item, index) => {
return (
<MenuItem key={index} value={item.value}>{item.label}</MenuItem>
)
})}
</Select>
)
父组件相关部分代码:
const [currentCustomer,setCurrentCustomer] = useState('all');
useEffect(() => {
console.log('Father useEffect');
}, [currentOrg, application, startDate, endDate, currentCustomer]);
//或者这里不监听currentCustomer也正常。useEffect里面有逻辑,都被我注释了就不贴了。
const customerChangeHandler = (newCustomer) =>{
// setBookStatus();
setCurrentPage(1);
setSearchKeyWords("");
setCurrentCustomer(newCustomer); //这句注释就正常了。
}
//上面的子控件
<CustomerSelector org={currentOrg} onValueChange={customerChangeHandler} />
当在页面上手动更换选项时,输出结果:
onValueChange
Child useEffect
Father useEffect
就百思不得其解,为什么Child useEffect会被触发呢?而且这还是我注释到最简了,按本来逻辑来的话会触发更多次。求React大🐂们看一看帮忙分析一下谢谢!
你好,
我分析了你的代码,发现 Child useEffect 被触发的原因是,你在 useEffect 的依赖列表中指定了 currentCustomer 变量。currentCustomer 变量是父组件传递给子组件的,它会随着父组件的渲染而变化。因此,当父组件渲染时,Child useEffect 就会被触发。
要解决这个问题,你可以将 currentCustomer 变量从 useEffect 的依赖列表中删除。这样,Child useEffect 只会在子组件第一次渲染时被触发。
以下是修改后的代码:
useEffect(() => {
console.log("Child useEffect");
// 从服务端获取,目前暂时注释了,注释与否都不影响现象。
}, []);
const onValueChange = (event) => {
console.log("onValueChange: " + event.target.value);
setCurrentCustomer(event.target.value);
if (props.onValueChange) {
props.onValueChange(event.target.value);
}
}
return (
<Select
value={currentCustomer}
variant="outlined"
color="primary"
fontSize="small"
className={classes.select1_3}
classes={{ select: classes.outlinedPadding }}
onChange={onValueChange}
>
{customers && customers.length > 0 && customers.map((item, index) => {
return (
<MenuItem key={index} value={item.value}>{item.label}</MenuItem>
)
})}
</Select>
);
希望这对你有帮助。
抱歉,这条注释去掉://或者这里不监听currentCustomer也正常。useEffect里面有逻辑,都被我注释了就不贴了。
父组件里不监听currentCustomer也还是会触发Child useEffect,就是注释了也不会正常。