This project was bootstrapped with Create React App.
npm install redux --save
npm install react-redux --save
npm install redux-observable --save
import { createStore, applyMiddleware, combineReducers } from 'redux';
import { Provider } from 'react-redux';
For the complete file check here at this point in time.
import { createStore, applyMiddleware, combineReducers } from 'redux';
import { Provider } from 'react-redux';
import { rootReducer } from './store/root';
const store = createStore(rootReducer);
ReactDOM.render((
<Provider store={store}>
<App />
</Provider>
), document.getElementById('root'));
import React, { Component } from 'react';
import logo from './logo.svg';
import MyComponentButton from './containers/MyComponentButton'
import './App.css';
class App extends Component {
render() {
return (
<div className="App">
<MyComponentButton />
</div>
);
}
}
export default App;
import storeFlags from './reducer';
import { applyMiddleware, combineReducers } from 'redux';
export const rootReducer = combineReducers({
storeFlags,
});
const defaultState = {
flag: false
}
export default function reduce(state = defaultState, action = {}) {
switch (action.type) {
default:
return state;
}
}
import React, { Component } from 'react';
import { connect } from 'react-redux';
class MyComponentButton extends Component {
constructor(props) {
super(props);
this.processClick = this.processClick.bind(this);
}
render() {
return (
<div>
{this.props.flag}
<button onClick={(e)=>{this.processClick(e)}}>click</button>
</div>
);
}
}
function mapStateToProps(state, ownProps) {
return {
flag : state.storeFlags.flag,
};
}
export default connect(mapStateToProps)(MyComponentButton);
export const ACTION_FLAG_ON = 'ACTION_FLAG_ON';
import * as types from './actionTypes';
export function command_setFlagOn() {
return {
type : types.ACTION_FLAG_ON,
}
}
import * as types from './actionTypes';
const defaultState = {
flag: false
}
export default function reduce(state = defaultState, action = {}) {
switch (action.type) {
case types.ACTION_FLAG_ON:
return Object.assign({}, state, {
flag : true,
});
default:
return state;
}
}
Let's move from a click button -> flag to true, to an epic so the click changes state from 0 then to 1 plus delay up to 2.
import { applyMiddleware, combineReducers } from 'redux';
import { combineEpics } from 'redux-observable';
import storeFlags from './reducer';
import { flagFlip } from './epics';
export const rootReducer = combineReducers({
storeFlags,
});
export const rootEpic = combineEpics(
flagFlip,
);
export const ACTION_FLAG_1 = 'ACTION_FLAG_1';
export const ACTION_FLAG_2 = 'ACTION_FLAG_2';
import * as types from './actionTypes';
import { filter, delay, mapTo } from 'rxjs/operators';
import { ofType } from 'redux-observable';
export const flagFlip = action$ => action$.pipe(
filter(action => action.type === types.ACTION_FLAG_1),
delay(1000),
mapTo({ type: types.ACTION_FLAG_2 })
);
import * as types from './actionTypes';
const defaultState = {
flag: 0
}
export default function reduce(state = defaultState, action = {}) {
switch (action.type) {
case types.ACTION_FLAG_1:
return Object.assign({}, state, {
flag : 1,
});
case types.ACTION_FLAG_2:
return Object.assign({}, state, {
flag : 2,
});
default:
return state;
}
}
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
/* Redux setup */
import { createStore, applyMiddleware, combineReducers } from 'redux';
import { Provider } from 'react-redux';
import { createEpicMiddleware } from 'redux-observable';
import { rootReducer } from './store/root';
import { rootEpic } from './store/root';
const epicMiddleware = createEpicMiddleware();
const store = createStore(rootReducer, applyMiddleware(epicMiddleware));
epicMiddleware.run(rootEpic);
ReactDOM.render((
<Provider store={store}>
<App />
</Provider>
), document.getElementById('root'));