gpt4 book ai didi

javascript - 功能组件状态持久化

转载 作者:行者123 更新时间:2023-11-30 10:58:59 24 4
gpt4 key购买 nike

我有一个 React 功能组件,我正在使用 Socket.io。每次 Socket 连接服务器失败(每 4 秒自试一次)它调用函数 ioConnectError

预期行为:如果 state 不是 lost 调用 setState('lost')。如果当前 state 已经 lost - 什么都不做。

当前行为:在函数 ioConnectError 中状态一直是 ok(这是默认值),即使它已被设置为丢失。它会导致组件的双重重新渲染。

const ConnectionStatus=(props)=> {
let [state, setState] = useState('ok');

const ioConnectError=()=> {
console.log(state); //this is always default value ('ok') - why?
state !== 'lost' && setState('lost');
}

const ioReconnect=()=> {
state !== 'reconnected' && setState('reconnected');
}

useEffect(() => {
console.log('useEffect'); // this is being called only once, on mount
props.io.on('connect_error',ioConnectError); // being called every 4 seconds
props.io.on('reconnect',ioReconnect);
return () => {
props.io.removeListener("connect_error",ioConnectError);
props.io.removeListener("reconnect",ioReconnect);
}
}, [])

return state;
}

最佳答案

问题在于 ioConnectError 词法范围内的 state !== 'lost' 求值,state 将始终引用初始值。

尝试将 ioConnectError 移动到 useEffect 范围(因为它在组件范围内是多余的,并且会在每个渲染器上分配一个新的未使用的函数)并使用函数式 useState 而不是(始终引用当前状态)。

另外,请注意这是一个自定义钩子(Hook)而不是一个组件,最好用“use”前缀来调用它:

const useConnectionStatus = ({ io }) => {
const [state, setState] = useState('ok');

useEffect(() => {
const ioConnectError = () => {
setState(state => {
if (state !== 'lost') {
return 'lost';
}
return state;
});
};

io.on('connect_error', ioConnectError);
return () => {
io.removeListener('connect_error', ioConnectError);
};
}, []);

return state;
};

引用 - Closures .

关于javascript - 功能组件状态持久化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58709393/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com