Simple React-Redux Starter Step By Step
This is a step-by-step guide to build a React project with Redux:
1 — Start the react project with the command:
npx create-react-app name-of-the-app
2 — Once the project is created, change to its directory
cd name-of-the-app
3 — Install ‘redux’ and ‘react-redux’ libraries (via npm or yarn)
npm install react-redux
npm install redux
or
yarn add react-redux
yarn add redux
4 — On index.js there are many things to do:
- create the store, importing the function createStore and assiging a constant to it
— wrap the App component with a Provider component (imported from ‘react-redux’
— import the rootReducer, which is still not created, to pass it as a parameter to the createStore function
import { createStore} from ‘redux’;
import { Provider } from ‘react-redux’;
import rootReducer from ‘./reducers/root.reducer’;const store = createStore(rootReducer);
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById(‘root’)
);
5 — root.reducer.js
A root reducer is a file where all the application reducers are combined.
For that, a combineReducers function must be import from ‘redux’, along with all the other reducers you might have.
We will export a constant named rootReducer, which will be assigned to to combineReducers function with an object as a parameter
This object will contain a key and its respective reducer.
The name of of this key is important to access the states from the other reducers!
import { combineReducers } from ‘redux’;
import otherReducer from ‘./other.reducer’;
import anotherReducer from ‘./another.reducer’;const rootReducer = combineReducers({
otherReducerKeyName: otherReducer,
anotherReducerKeyName: anotherReducer
})export default rootReducer
6 — other.reducer.js
This is the base of an reducer file.
It function receives a state (with initialState as default) and a action from the dispacth and some other variables inside the payload.
const initState = {
paramether: initial_value
}const otherReducer = (state = initState, action) => {
switch (action.type){
case ‘ACTION_TYPE_1’:
return {
…state,
paramether: new value
}
case ‘ACTION_TYPE_2’:/// logic goes here
return {
…state,
paramether: new value
}
default:
return state}
}export default otherReducer
7 — Component.jsx
In the component file we must:
— import React and component from react
— import the function connect from react-redux
— create the mapState function to GET data from the store
— create the dispatchState function to SEND an action and possibly a payload (data) to the store
connect function: it will be used at the end of the file, on the export, passing the mapState and dispatchState as parameters:
export default connect(mapState, dispatchState)(ComponentName);
mapState: it must be declared at the body of the class, receiving a state as a parameter and with a return an object.
the objects key is how the state variable is accessed inside the class, with: this.props.variable_key
its value will be: state.key_name_in_root_reducer.key_name_in_specific_reducer
const mapState = (state) => {
return {
variable_key: state.key_name_in_root_reducer.key_name_in_specific_reducer
}
}
dispatchState: the dispacth function receives the dispatch as its argument.
it also returns a object. whenever its key is called inside the component (e.g. by a onClick event), it will trigger its value.
the value is a arrow function with a dispatch in its callback.
in its turn, the dispatch function will also have a object as a parameter, with at least one key: type with its action as the value
we you can also send a payload with any other data that will be used in the reducer:
const dispatchState = (dispatch) => {
return {
doSomething: () => dispatch({
type: ‘ACTION_TYPE_1’,
payload: ///
})
}
}
example of a complete file:
import React, {Component} from ‘react’;
import { connect } from ‘react-redux’;class ComponentName extends Component {
render() {
const handleClick = () => {
this.props.addingOne()
}return (
<div><h2>Count: {this.props.cnt}</h2>
<button onClick={handleClick}>Add 1</button>
</div>
);
}}
const mapState = (state) => {
return {
cnt: state.counter.count
}
}const dispatchState = (dispatch) => {
return {
addingOne: () => dispatch({
type: ‘ACTION_TYPE_1’,
})
}
}
export default connect(mapState, dispatchState)(ComponentName);
Applying redux, the state in your application will be stable and easly accessed in all your components!