0

Edit - Fixed The problem was absolute garbage redux code as it was my first time using it. I studied Redux and rewrote my code and it works fine. It wasn't working because there was way too much garbage code working at once.

I'm using nextJS and when visiting a shared URL such as /username/p/postID I want to display the initial post modal/popover.

    async function presentInitialPost(postID: string) {
        const postSnap = await db.collection("posts").doc(postID).get();
        const postData = postSnap.data();
        if(postData){
            dispatch(showModalPostView(postData as Post));
        }
    }

    useEffect(() => {
        if(initialPostID){
            presentInitialPost(initialPostID)
        }
    }, [initialPostID])

Errors (there ae numerous of each): "You may not unsubscribe from a store listener while the reducer is executing." "You may not call store.getState() while the reducer is executing."

I use the same dispatch throughout my app just fine - and if I call presentInitialPost on a button click instead - it works completely fine.

I've tried delays and debugging where the error is coming from but I haven't figured it out at all, any help is appreciated, thank you.

Redux code:

showModalPostView(state, action) {
  state.showModalPostViewFunction(action.payload);
},

setShowModalPostViewFunction(state, action) {
  state.showModalPostViewFunction = action.payload;
  return state;
},

showModalPostViewFunction: (post: Post) => {},

showModalPostViewFunction comes from my overlay wrapper component

    showModalPostView = (post: Post) => {
        console.log(this.state)
        this.setState({
            showModalPostView: true,
            modalPostViewPost: post,
        });
    };

When the modal post view is shown here, it contains multiple useSelectors which cause the errors - but only when i present the modal post view in useEffect - it works just fine throughout the app when dispatched through a click action.

In modal post view various selectors throw the errors:

const likedPosts = useSelector((state: ReduxRootState) => state.likedPosts);
11
  • Can you share the actual error message(s)? Commented Apr 5, 2022 at 3:34
  • @Jacob They're in the question: "You may not call store.getState() while the reducer is executing." "You may not unsubscribe from a store listener while the reducer is executing." Commented Apr 5, 2022 at 3:36
  • It sounds like an issue in your reducer then; can you post your reducer code? Commented Apr 5, 2022 at 3:37
  • @Jacob I just did, I think the issue might have to do with react strict modes double render calling the useSelectors twice, but I just can't figure it out. Everything works fine if I remove the useSelectors in the modal view itself Commented Apr 5, 2022 at 3:45
  • 1
    Since you're saying it works well elsewhere but causes problems only in useEffect, possibly the dispatch function is called more than once, try calling the presentInitialPost(initialPostID) without any dependency values in useEffect Commented Apr 5, 2022 at 4:01

1 Answer 1

1

It appears you are not using redux the way it was intended to be used. What you pass to dispatch() is supposed to be an action. A reducer receives that action and returns new state, and then then new state is sent to your subscriber (the React component).

You are instead calling a function showModalPostView which is calling some setState function in the parent component and is returning who knows what. That return value is being passed as an argument dispatch, which kicks off a reducer. However, that setState is likely causing your child component to unsubscribe from the store so it can re-render.

It like you aren't actually dispatching an action; you're just calling a function, so you shouldn't be using dispatch at all.

async function presentInitialPost(postID: string) {
    const postSnap = await db.collection("posts").doc(postID).get();
    const postData = postSnap.data();
    if(postData){
        showModalPostView(postData as Post);
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

I appreciate the redux knowledge and am going to study this and spend the day rewriting my redux code completely. Although dispatch is required here as without neither the function in the state, or the one that replaces via another dispatch from the overlay wrapper gets called. When importing showModalPostView it shows the type as ActionCreatorWithPayload<any, string>, not a function.
An action creator is a function that , but the showModalPostView function you posted isn't returning an action. Based on that name, it looks like you're using redux toolkit which I'm not familiar with. Will add a tag to your question to hopefully catch experts in that library since this does not look like vanilla redux.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.