#984·rematch

[Question] Best practice on call this in reducers and get updated state in effects.

Author: pingfengafeiCreated Sep 11, 2023Updated Sep 12, 2023
Labelsdocs

Hi Rematcher, need help to answer this two best practice for two scenario.

// models files named: foo.js

export {
   models: {
      foo: {};
   },
   reducers: {
      const upldateFoo = (state, foo) => ({ ...state, foo });
      const updateFooProperties = (state, properties) => {
         const foo = { ...state.foo, ...properties};
        // Question here call this method in reducers.
        return this[foo/upldateFoo](state, foo);
      }
   },
   effects: {
       const update(foo){
         // error here: nextFoo is a Promise since not await this.updateFoo
          const nextFoo = this.updateFoo(foo);
        
         // question here: don't want to use async in effect here, to get the latest state, I called getState method from redux. 
         //  now get the correct one.
         const nextFoo = getState().foo.foo;
     }
   }
}

My question is: does the two resolve way are best practice in rematch.

1. Call this in reducers.
2. getState in effects.

Thinking about 1: Call this in reducers.

I thinks reducers and effects are extended from redux reducer and side-effect. it is quite common with computing states via compose reducers in redux, I didn't check the detail implementation of this in rematch, it seems that rematch does not recommend using this in effect so that design a strange pattern with: this[modelName/reducerMethodName] instead of using this in effects: this.effectMethodName

Thinking about 2: getState in effects.

It is not a wildly used but really existing case in real world: get the latest state after state updated in a effect, like:

onEffect() {
   this.onReducer1();
   // have to get the updated state to do other things
  this.onReducer2();
  // have to get the updated state to do other things
}

At very beginning, I suppose reducer method return object directly, like this:

const nextState = this.onReducer();

However, nextState is a Promise not object.

Hoho, let's await the result:

const nextState = await this.onReducer();

sadly, nextState also is not the nextState as expected. it returns:

   { type: modeName/reducerName, payload}

so can not get nextState from reducer method response.

Now seems there are only two ways to get the latest state:

options 1: getState() as mentioned above.

options 2: call another effects:

onEffect() {
   this.onReducer1();
   this.onEffectComplted();
}

onEffectCompleted(_, state) {
   // now state is the latest one and do work on the state.
   this.onReducer2();
  this.onEffectCompletedCompleted();
}

onEffectCompletedCompleted(_, state) {
  // now state is the latest one and do work on the state.
}

Now this pattern becomes effect compose which seems not recommended in reducer compose.