简体   繁体   English

如何在完成提取之前使用 redux 清除 redux state 重击?

[英]How to clean up redux state with redux thunk when unmounting component before finishing fetch in useEffect?

After some time working with react-redux and redux thunk I have realise about a behaviour, which isnt the best user experience.在使用 react-redux 和 redux thunk 一段时间后,我意识到了一种行为,这不是最好的用户体验。

I know that when you are working with react and you are fetching data in useEffect when the component is rendering and for any reason you go back or navigate somewhere else you need to clear the state with a function in the return (which will recreate the componentWillUnmount lifecycle) I know that when you are working with react and you are fetching data in useEffect when the component is rendering and for any reason you go back or navigate somewhere else you need to clear the state with a function in the return (which will recreate the componentWillUnmount生命周期)

This problem I am facing however occurs when working with redux thunk because the data fetch is with the actions creators.然而,我面临的这个问题发生在使用 redux thunk 时,因为数据获取是由动作创建者完成的。 So to make my long story short I will show some code.所以为了长话短说,我将展示一些代码。 The fetching action looks something like this:获取操作如下所示:

export const fetchData = () => async (dispatch, getState) => {
 try {
    dispatch(fetchDataStart())
    const response = await fetch('https://jsonplaceholder.typicode.com/photos')
    dispatch(fetchDataSucess(data))
 } catch (error) {
     console.log(error)
 } 
}

Let's say that I call this action in my component useEffect like this:假设我在我的组件 useEffect 中调用此操作,如下所示:

useEffect(() => {

  const loadData = async () => {
    await dispatch(fetchData())
  }

  loadData()

  return () => dispatch(resetData())
},[ ])

As you can see I am dispatching a resetData action to clear the state when the component unmounts BUUUUT this is where the problem arrives.如您所见,当组件卸载 BUUUUT 时,我正在调度一个 resetData 操作以清除 state,这就是问题所在。 If before fetching the data the user navigates to another page, the resetData will be dispatched BUT as the fetch could not be finished the data will be stored after having been reseted.如果在获取数据之前用户导航到另一个页面,resetData 将被调度,但由于获取无法完成,数据将在重置后存储。 So when the user navigates back to that component it will blink (show only very quickly, maybe for a second) the old data before loading the new one.因此,当用户导航回该组件时,它会在加载新数据之前闪烁(仅非常快速地显示,可能会显示一秒钟)旧数据。 So is there any way to avoid this problem with redux thunk?那么有什么办法可以避免 redux thunk 出现这个问题吗?

PD: I could block the navigation or the whole screen with a backdrop so the user wont navigate until the fetch is finished but i feel like that is kind of a workaround of the problem. PD:我可以用背景阻挡导航或整个屏幕,这样用户在获取完成之前不会导航,但我觉得这是一种解决问题的方法。 However, let me know if you think that this would still be the best way.但是,如果您认为这仍然是最好的方法,请告诉我。

Thank you.谢谢你。

You can create an AbortController instance.您可以创建一个 AbortController 实例。 That instance has a signal property, and we pass the signal as a fetch option.该实例具有信号属性,我们将信号作为获取选项传递。 Then to cancel data fetching we call the AbortController's abort property to cancel all fetches that use that signal.然后为了取消数据获取,我们调用 AbortController 的 abort 属性来取消所有使用该信号的获取。

export const fetchData = () => async (dispatch) => {
 try {
    const controller = new AbortController();
    const { signal } = controller;        
    dispatch(fetchDataStart(controller)); // save it to state to call it later
    const response = await fetch('https://jsonplaceholder.typicode.com/photos', { signal });
   dispatch(fetchDataSucess(data));
 } catch (error) {
 console.log(error);
 } 
}

useEffect:使用效果:

useEffect(() => {
   dispatch(fetchData());
   return () => dispatch(resetData()) // resetData will call controller.abort() that was saved in state
},[ ])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM