Using redux with FuseJS

Most of the users know hot to use redux, when it’s good, and when it’s not.
FuseJS provides us with observables, which are extremely good for any state management.

But I prefer to have predictable and immutable global state, and redux can solve this problem.

So, first of all, let’s create a new project and add redux package from npm.

        npm init .
        npm install redux --save

Now, let’s get into store configuration:

store.js
import {
  createStore,
  combineReducers
} from "node_modules/redux/dist/redux.js";

// our dumb reducer
function counter(state = 0, action) {
  switch (action.type) {
    case "INCREMENT":
      return state + 1;
    case "DECREMENT":
      return state - 1;
    default:
      return state;
  }
}
//use combineReducers to make sure, we support this redux feature
const reducers = combineReducers({
  counter: counter
});
//export our store, so that we able to get it inside other components
export const store = createStore(reducers);

Now, let’s create a basic redux-connected class, so that we can reuse it in our components:

import {store} from '../store';

export default class ReduxComponent {
    constructor(mapStateToProps) {
        // this is the function, which will take state and give us actual props
        this.mapStateToProps = mapStateToProps;
        // with this, in other classes we can just call this.dispatch to emit action
        this.dispatch = store.dispatch.bind(store);
        // get initial props
        this.updateProps(store.getState());
        // subscribe to store changes
        store.subscribe(()=>{
            this.updateProps(store.getState());
        })
    }
    // this will make props field immutable
    updateProps(state) {
        this.props = Object.assign({},this.props, this.mapStateToProps(state));
    }
}

Now, let’s create our actual model

import ReduxComponent from 'fuse-redux/ReduxComponent';

export default class TodoApp extends ReduxComponent {
  // this is function we gonna use to map state to props
  static mapStateToValues(state) {
    return {
      counter: state.counter,
    };
  }
  constructor() {
    super(TodoApp.mapStateToValues);
  }

  increment(title) {
    this.dispatch({ type: "INCREMENT" });
  }
  decrement(title) {
    this.dispatch({ type: "DECREMENT" });
  }
}

And here we go, let’s create our first redux-connected UX Component:

<App Model="TodoApp">
  <Panel>
    <StackPanel>
      <Text Value="{props.counter}"/>
      <Button Clicked="{increment}">
        <Text Value="Increment" />
      </Button>
      <Button Clicked="{decrement}">
        <Text Value="Decrement" />
      </Button>
    </StackPanel>
	</Panel>
</App>

There is also a way to use redux-logger and possibly redux-dev-tool.

3 Likes