最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to execute store.unsubscribe from useEffect using React hooks and Redux - Stack Overflow

programmeradmin7浏览0评论

I have a React stateless ponent 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 ponent. 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?

I have a React stateless ponent 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 ponent. 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?

Share Improve this question asked Nov 25, 2019 at 15:16 user3174311user3174311 1,9938 gold badges36 silver badges78 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 12

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 ponent 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;
}, []);

Return a function from useEffect to do cleanup. So the returned function will be called when the ponent 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/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;
}, []);

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 ponent, 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 ponent can just specify what data it needs.

发布评论

评论列表(0)

  1. 暂无评论