Nikita Rybak
Nikita Rybak

Reputation: 68006

Rendering gets triggered in the middle of a redux update

Are redux updates synchronous? Can we expect an entire update to complete before rendering code is triggered?

Let's say you have a middleware which catches an event from one redux store and updates a different redux store accordingly, to keep them in sync.

const MyMiddleware: Middleware = (store: MiddlewareAPI<AppDispatch, RootState>) => (next) => (action) => {
    console.log('MyMiddleware start');
    const result = next(action); // apply reducer1

    if (action.type === reducer1Types.SET_ACTIVE_WORKSPACE) {
        console.log(`MyMiddleware middle`);
        store.dispatch(reducer2Actions.initializeWorkspace(action.payload.workspace));
    }

    console.log(`MyMiddleware end`);
    return result;
};

However, for some reason, App.jsx#render function is invoked when reducer1 is already updated and reducer2 is not run. In the console, it would be

> MyMiddleware start
> <logging from App.jsx#render>
> MyMiddleware middle
> MyMiddleware end

Is this expected?

When I trace this code, I also see that it goes into rendering logic before exiting middleware: enter image description here

The store setup:

export const store = configureStore({
    reducer: {
        reducer1: reducer1.reducer,
        reducer2: reducer2.reducer,
    },
    middleware: (getDefaultMiddleware) =>
        getDefaultMiddleware().prepend(MyMiddleware),
});

Upvotes: -1

Views: 60

Answers (1)

Nikita Rybak
Nikita Rybak

Reputation: 68006

Just needed to use the batch api. (Running React 16)

const MyMiddleware: Middleware = (store: MiddlewareAPI<AppDispatch, RootState>) => (next) => (action) => {
    let result = null;
    batch(() => {
        result = next(action);
        if (action.type === reducer1Types.SET_ACTIVE_WORKSPACE) {
            store.dispatch(reducer2Actions.initializeWorkspace(action.payload.workspace));
        }
    });
    return result;
};

Batching logic seems to be applied by default in some cases, but not others (more info).

Upvotes: 0

Related Questions