【问题标题】:How to execute store.unsubscribe from useEffect using React hooks and Redux如何使用 React hooks 和 Redux 从 useEffect 执行 store.unsubscribe
【发布时间】:2020-03-20 22:15:15
【问题描述】:

我有一个使用 redux 和 hooks 的 React 无状态组件。我需要在页面加载时显示项目数(useEffect)并在每次添加或删除项目时更新它(store.subscribe)

useEffect(() => {
    setState({
        items: store.getState().items.length
    });
}, []);

store.subscribe(() => {
    setState({
        items: store.getState().items.length
    });
});

但这会导致控制台显示警告无法对未安装的组件执行 React 状态更新。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要解决此问题,请在 useEffect 清理函数中取消所有订阅和异步任务。 .

如何从 useEffect 中取消订阅?

【问题讨论】:

    标签: javascript reactjs redux react-hooks


    【解决方案1】:

    如果将 useEffect 调用的第二个参数设置为 [],效果回调函数将充当 ComponentDidMount。如果该回调函数返回一个函数,则该函数将在组件卸载之前调用(ComponentWillUnmount)。

    我猜这个 setState 应该替换为 setItems,如下所示。 请尝试此代码。

    const [items, setItems] = useState([]);
    useEffect(() => {
        setItems(store.getState().items.length);
        
        
        const unsubscribe = store.subscribe(() => {
            setItems(store.getState().items.length);
        });
        
        return unsubscribe;
    }, []);

    【讨论】:

      【解决方案2】:

      从 useEffect 返回一个函数来进行清理。因此,当组件卸载时,将调用返回的函数。

      store.subscribe 返回一个取消订阅函数。使用useRef 挂钩保存其引用,并从useEffect 挂钩返回相同的引用。

      在文档中了解它:https://reactjs.org/docs/hooks-effect.html#effects-with-cleanup

      const storeRef = useRef(() => {});
      useEffect(() => {
        storeRef.current = store.subscribe(() => {
          setState({
            items: store.getState().items.length
          });
        });
      
        return storeRef.current;
      }, []);
      
      useEffect(() => {
        setState({
          items: store.getState().items.length
        });
      
        return storeRef.current;
      }, []);
      

      【讨论】:

        【解决方案3】:

        你不应该像那样直接使用商店。

        如果您需要从存储中读取值作为组件的一部分,您应该使用为您工作的 React-Redux API:connectuseSelector。他们已经根据需要管理了订阅和取消订阅商店的工作,因此您的组件可以只指定它需要的数据。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-05-07
          • 2020-03-23
          • 2020-08-02
          • 2020-06-08
          • 2021-03-30
          • 2019-08-16
          • 2020-01-30
          • 2020-11-01
          相关资源
          最近更新 更多