ice-lab / icestore

🌲 Simple and friendly state for React
MIT License
397 stars 35 forks source link

Classic redux dispatch? #114

Closed avalanche1 closed 4 years ago

avalanche1 commented 4 years ago

I'd like to use classic redux approach where action is passed to dispatch. Is it possible? Without specifying in event handler which particular reducer should be invoked. I can see that there is a dispatch arg in effects fn and also a vague notion of actions in type definitions. But I didn't see anything particular in the api docs. Do I always have to specify which particular reducer I want to use? What if my action requires several reducers invoked simultaneously?

alvinhui commented 4 years ago
  1. I'd like to use classic redux approach where action is passed to dispatch. Is it possible?

    
    import { createStore } from '@ice/store';
    
    const counter = {
      state: 0,
      reducers: {
        increment:(prevState) => prevState + 1,
        decrement:(prevState) => prevState - 1,
      },
      effects: () => ({
        async asyncDecrement() {
          await delay(1000);
          this.decrement();
        },
      }),
    };
    
    const models = {
      counter,
    };
    
    const { dispatch } = createStore(models);
    
    dispatch({ type: 'counter/increment', payload: 'foo' });
    ``
  2. What if my action requires several reducers invoked simultaneously?

    const { useModel } = createStore(models);
    
    function() {
      const {, dispatchers} = useModel('counter');
    
      dispatchers.increment();
      dispatchers.decrement();
    }
avalanche1 commented 4 years ago
  1. Thanks, looking great! Could you amend the Recipes section, plz?
  2. What I was talking about is:
    const counter = {
    state: {
    A: "",
    B: ""
    },
    reducers: {
    setA:(prevState, text) => prevStat.A = text,
    setB:(prevState, textB) => prevState.B = textB,
    },
    };

    If I call setA('foo'); setB('bar'); setB('baz'); setA('bam'); sequentially - each call will cause a rerender of all the componetes that have subscribed to state. In my particular case my components are very heavy and multiple rerenders will cause lagginess to the UI. What I was asking about is a way to accumulate all the updates and then apply them all in one go. Currently I have to do it in-memory - collect all updates to the accumulator object and then pass it to a single setState reducer, instead of having multiple segregated reducers.