Search code examples
javascriptreactjsfluxreactjs-flux

How do you change Object values with Flux Stores?


Since Facebook removed Flux's MapStore, I'm having a hard time figuring out the best way to mutate an object in its store.

ReduceStore is supposed to be able to handle this problem, and The Pro-React book by Cássio de Sousa Antonio has several examples of ReduceStore, but none of them highlight this functionality, and I'm a bit lost.

class MyObjectStore extends Flux.ReduceStore {

  getInitialState(){
    return {
      foo: '',
      bar: '',
      baz:''
    };
  }

  reduce(state, action){
    switch (action.type) {
      case constants.CHANGE_FOO:
        return state.set('foo', action.value)
      case constants.CHANGE_BAR:
        return state.set('bar', action.value)
      case constants.CHANGE_BAZ:
        return state.set('baz', action.value)
      default:
        return state;
    }
  }
}

export default new MyObjectStore(AppDispatcher);

// => TypeError: state.set is not a function

I tried:

state.foo = action.value;
 return state;

but doing this doesn't trigger any changes.

UPDATED:

Using Immutable worked:

import Immutable, {Map} from 'immutable';

class MyStore extends ReduceStore {

  getInitialState(){
    return Map({
      foo: '',
      bar: '',
      baz: ''
    });
  }

  reduce(state, action){
    switch (action.type) {
      case constants.CHANGE_FOO:
        return state.set('foo', action.value)
      case constants.CHANGE_BAR:
        return state.set('bar', action.value)
      case constants.CHANGE_BAZ:
        return state.set('baz', action.value)
      default:
        return state;
    }
  }
}

However, now in the rendering methods, I have to be careful to use Map's getter functions, ex:

const bar = this.props.foo.get('bar');


Solution

  • Your initial state is a plain object, but your reduce seems to be opperating on Immutable objects. This means when reduce is called the first time, state is a plain object with no set property, giving you the TypeError you mention. Changing your getInitialState to return an immutable map (eg wrap what you have in Map(...)) will fix it.