How to execute store.unsubscribe from useEffect using React hooks and Redux

半城伤御伤魂 提交于 2019-12-13 03:34:59

问题


I have a React stateless component using redux and hooks. I need to display the number of items on page load (useEffect) and update it every time I add or remove an item (store.subscribe)

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

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

but this is causing the console to display the warning Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function. .

How can I unsubscribe from inside useEffect?


回答1:


If you set the second parameter of useEffect call to [], the effect callback function would act as ComponentDidMount. If that callback function returns a function, this function will be called just before the component is unmounted(ComponentWillUnmount).

And I guess this setState should be replaced with setItems as below. Please try this code.

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



回答2:


Return a function from useEffect to do cleanup. So the returned function will be called when the component gets unmounted.

store.subscribe return an unsubscribe function. Save its reference using useRef hook and return the same reference from the useEffect hook.

Read about it in the docs: 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:


You shouldn't be using the store directly like that in the first place.

If you need to read values from the store as part of the component, you should use the React-Redux APIs that do that work for you: connect and useSelector. They already manage the work of subscribing and unsubscribing to the store as needed, so that your component can just specify what data it needs.



来源:https://stackoverflow.com/questions/59034923/how-to-execute-store-unsubscribe-from-useeffect-using-react-hooks-and-redux

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!