如何避免 React 组件生命周期中的间隙

问题描述 投票:0回答:1

我目前正在学习如何在 React 中使用函数组件,并遇到了一些计时问题。看起来,应该触发重新渲染的事件是在组件渲染和 useEffect 挂钩调用之间调用的。这两者之间是否存在允许执行异步事件的延迟?我该如何防止这种“差距”? (我不记得当时每个人都对类组件和用于注册事件监听器的 componentDidMount 函数有这样的问题)。

给定这个组件(具有非常简化的类型和逻辑):

// global variable. May have already been updated from before CounterDisplay is even rendered the first time
let globallyStoredCounter = 0; 

export default function CounterDisplay(): React.JSX.Element {
    useEvent('counter_changed_event');

    console.log('Start rendering CounterDisplay: ', globallyStoredCounter);
    return (
        <div>{globallyStoredCounter}</div>
    );
}

使用此自定义事件挂钩:

export function useEvent(eventName: string) {
    const [lastEventInstance, setEventInstance] = useState<object>({});

    useEffect(() => {
        function handleEvent(event: object) {
            console.log('Trigger a rerender by updating the state with a new object');
            setEventInstance(event);
        }

        console.log('Listening to event ' + eventName);
        window.addEventListener(eventName, handleEvent);
        return () => {
            console.log('Stop listening to event');
            window.removeEventListener(eventName, handleEvent);
        };
    }, [lastEventInstance]);
    return [lastEventInstance];
}

最后是调度事件的代码。这是通过按下相同的按钮来执行的,这也会触发 CounterDisplay 组件进行渲染。

fetch('http://localhost/api/something').then(_ => {
   globallyStoredCounter += 1;
   console.log(`Notifying event "counter_changed_event" with data`, {counter: globallyStoredCounter});
   window.dispatchEvent(new Event('counter_changed_event'));
}); 

我在控制台中得到以下输出:

> Start rendering CounterDisplay: 0
> Notifying event "counter_changed_event" with data {counter: 1}
> Listening to event counter_changed_event

虽然 HTML 输出一直显示值 0。 需要明确的是:是的,{counter: 1} 对象是一个全新的对象,它与以前的对象肯定有细微的不同。

我希望有人可以帮助我解决这个问题,因为目前这是一个令人讨厌的竞争条件。


编辑:因为看起来我没有很好地解释我的问题(对此感到抱歉!),我更新了上面的代码以包括如何调用事件,这里有更多信息,这将(希望)使它更清楚:

情况: 我得到了如上所述的组件和钩子,并希望始终显示我的

globallyStoredCounter
的当前值(这应该不重要,它何时或将被更新)。计数器本身异步更新并随后触发事件侦听器。

我的期望与现实: 如果

globallyStoredCounter
在渲染组件之前从外部更新,它会显示更新后的数字。 如果
globallyStoredCounter
在应用 useEvent 挂钩后更新,它会显示更新的数字。 但有时,在渲染和放置 useEffect 挂钩中的事件侦听器之间调用该事件,因此不会更新组件。

问题: 我肯定不是第一个或唯一一个拥有独立更新数据和反映此数据的组件的人。但如果渲染和 useEffect 挂钩之间发生更改,我不知道如何保持组件更新。谁能告诉我,如何避免这种差距并保持显示正确的数字?

javascript reactjs react-lifecycle
1个回答
0
投票

如果您在组件(和 React)外部存储变量,您将必须做大量工作来确保它是正确的,并且组件生命周期行为可能会在 React 版本之间发生变化。

我强烈建议尝试在 React 中找到一个解决方案来存储你的变量,无论是 prop、state、context 等等。

© www.soinside.com 2019 - 2024. All rights reserved.