简体   繁体   中英

Clear redux state when page transition

I made a blog and store the single page state to redux state (singlePost). When I go to a specific post page, the singlePost is set to the post value. But When I go back to my homepage and click the next post, the next post page shows the previous value and immediately turn to the new value.

I try to dispatch the reset function if user presses the browser's go back button, but it seems not work. Could someone guide me how I improve this? Thank you!

singlePostReducer.js

export const singlePostReducer = createSlice({
  name: "singlePost",
  initialState: {
    isLoadingPost: false,
    singlePost: "",
    newPostResponse: null,
  },
  reducers: {
    setIsLoadingPost: (state, action) => {
      state.isLoadingPost = action.payload.isLoading;
    },
    setSinglePost: (state, action) => {
      state.singlePost = action.payload;
    },
    setNewPostResponse: (state, action) => {
      state.newPostResponse = action.payload;
    },
    resetSinglePost: (state) => {
      state.singlePost = "";
    },
  },
});

SinglePost.js

 export default function PostPage() {
      const { id } = useParams();
      const singlePost = useSelector((store) => store.singlePost.singlePost);
      const { body, title, createdAt } = singlePost;
      const dispatch = useDispatch();
      const history = useHistory();

      //Does 
      if (history.goBack() || window.onpopstate) {
          dispatch(reset());
        }

      useEffect(() => {
        dispatch(getSinglePost(id));
        
      }, [id, dispatch]);
    
      return (
        <PostPageContainer>
          <h1>{title}</h1>
          <h4>{new Date(createdAt).toLocaleString()}</h4>
          <PostContent>{body}</PostContent>
        </PostPageContainer>
      );
    }

Issue

//Does
if (history.goBack() || window.onpopstate) {
  dispatch(reset());
}

The issue is that as written, history.goBack() will always be immediately invoked. I'm not sure what the return value is, but that isn't really relevant for you. window.onpopstate needs to have a callback assigned to it in order to work, but this also isn't want you want and assigning one would overwrite the global value and isn't recommended to do at all.

Solution

You can dispatch your rest action from an effect clean up function when the component unmounts.

export default function PostPage() {
  const { id } = useParams();
  const singlePost = useSelector((store) => store.singlePost.singlePost);
  const { body, title, createdAt } = singlePost;
  const dispatch = useDispatch();
  const history = useHistory();

  useEffect(() => {
    dispatch(getSinglePost(id));
  }, [id, dispatch]);

  useEffect(() => {
    return () => dispatch(reset()); // <-- reset when unmounting
  }, []);

  return (
    <PostPageContainer>
      <h1>{title}</h1>
      <h4>{new Date(createdAt).toLocaleString()}</h4>
      <PostContent>{body}</PostContent>
    </PostPageContainer>
  );
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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