FormidableLabs / freactal

Clean and robust state management for React and React-like libs.
MIT License
1.65k stars 46 forks source link

Effect that does not change state #63

Closed henryluki closed 7 years ago

henryluki commented 7 years ago

For example, effects like this:

effects: {
  commentVote: (effects, id) => {
    fetch(url, {
      method: "POST",
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        id: id
      })
    }).then(resp => {
      // response: { code: 200, result: 1}
      // do not change state here
      return resp
    })
  }
}

Use it:

effects.commentVote("78907890").then(resp => {
  if (resp.result === 1) {
    alert("Comment vote success!")
  }
})

In this case, commentVote doesn't change state. Promise.resolve returns an object.

export const getEffects = (hocState, effectDefs, parentEffects) => {
  const applyReducer = reducer => {
    const result = reducer ? reducer(hocState.state) : null;
    // In this case, reducer should be an object 
    // reducer = { code: 200, result: 1 }
    if (result) {
      hocState.setState(result);
    }

    return result;
  };

  const effects = Object.keys(effectDefs).reduce((memo, effectKey) => {
    const effectFn = effectDefs[effectKey];

    memo[effectKey] = (...args) => Promise.resolve()
      .then(() => effectFn(effects, ...args))
      .then(applyReducer);

    return memo;
  }, Object.assign({}, parentEffects));

  return effects;
};
divmain commented 7 years ago

Promise-returning functions that do not change state should not be defined as effects. Instead, they should be defined as a helper function. In freactal parlance, an effect is a promise-returning function whose resolution value is a function that reduces old state into new state.

If I misunderstood the question, however, please let me know and feel free to re-open the issue. I'm going to close the associated PR as well. But again, if I'm missing something, please just let me know! :)