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.