Redux - as simple as it can get
Clint Maruti
Posted on September 16, 2019
Redux, by it's definition, is a state management framework that can be used with different web technologies, including react and ruby. Redux is not part of react!
It is efficient when you are working on a large application that requires changing states in different components. Assuming you are working on an application that has over 10 components, and each component has its own local state, the entire state of the application can be managed on a single object housed in Redux store.
I am going to share some basic steps I use to set up redux.
Step 1: Creating your Initial State
A state in simple terms, is a JavaScript object that stores dynamic data that will be used in the components. This data determines the component's behaviour. Assuming Student represents your application's current state in time. Let's define our student current state:-
const initialState = {
name: 'Valerie',
grade: 4,
age: 8
};
Step 2: Defining your Action(s) and Action Creator(s)
An Action is simply a JavaScript object that contains information that send data from your application to your store. They are the only source of information for the store.
In our example, our actions can be to enroll a student, pay their fees or assign them a dormitory. Let's define an action. Defining a Redux action is as simple as declaring an object with a type property. We first declare our action type by assigning it to a constant variable. This is just best practice.
const ENROLL = 'ENROLL';
Next, we define our action creator which will be used to send the action to the store. An action creator is simply a JavaScript function that returns an action.
const enrollStudentAction = (status) => {
return {
type: ENROLL,
status: status
}
};
Step 3: Creating your reducer(s)
A Reducer describes how our state changes in relation to the actionsthat we have described. A reducer is a function that takes in the state as the first argument and action. Reducers in Redux are responsible for the state modifications. Reducers return a new state.
const studentReducer = (state = initialState, action) => {
switch (action.type) {
case ENROLL:
let newInitialState = Object.assign({},state);
newInitialState.status= action.message;
return newInitialState;
default:
return state;
}
}
N/B
In Redux, state is read-only i.e, the reducer function must always return a new copy of state and never modify state directly. Redux does not enforce state immutability, however, you are responsible for enforcing it in the code of your reducer functions.
In our case, our state is an object. In order to enforce state immutability in objects, we use Object.assign()
utility. Object.assign()
takes a target object and source objects and maps properties from the source objects to the target object. Any matching properties are overwritten by properties in the source objects.
So our Object.assign({},state)
utility takes in an empty object as the target object and our state which is our initialState
object as the source. This just creates a clone of our state. Now that we have our state object clone, we can then add a new property in it. Our new property is status and is set to a value 'enrolled'.
Step 4: Creating our store
As I mentioned above, the store houses our state and all the logic to update it are passed to it. To create our store, we use a createStore()
function from redux
. It takes the reducer, state - or if you like to call it preloaded state
and in some cases enhancers e.g. applymiddleware(). But I won't go in to that. I want to this as minimal as possible.
const store = Redux.createStore(studentReducer, initialState)
There we have our store ready!
State 6: Subscribe
Subscribe just lets you know every time the store changes. If you're writing a react-redux application then you never need it because react-redux does this for you. (i.e. essentially it watches for changes and then tells react to redraw). For example in our case, if we want to know whether the our student state is changing, we can add an event listener. It will be called any time an action is dispatched, and some part of the state tree may potentially have changed. You may then call getState() to read the current state tree inside the callback. For example, in our case, if we want to check whether a new student is enrolled or not, we can create an event listener called handleChange
like this:-
function handleChange() {
const currentStudent = store.getState();
if (currentStudent.status === 'enrolled') {
console.log('A new Student is enrolled!');
} else {
console.log('Student not yet enrolled!');
}
}
then we subscribe
this event to the store like this:-
store.subcribe(handleChange)
Finally Dispatching our actions
Dispatching simply means, passing the logic (actions) that we have created to the redux store. This is the moment of truth now. We can now test our update logic.
Dispatch method is what you use to dispatch actions to the Redux store. Calling store.dispatch()
and passing the value returned from an action creator sends an action back to the store.
store.dispatch(enrollStudentAction('Enrolled'));
We can check that our state changes by calling getState()
method on the store:-
// Log the initial state
console.log(store.getState()
Once you do this, you will see that our state now has status: 'enrolled'
` property at the bottom. We killed it!
Cheers!
Posted on September 16, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.