React子组件带参数useEffect不明原因触发多次

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,就是注释了也不会正常。