The world of Javascript is constantly changing. New libraries, new frameworks, new languages. It’s fun but sometimes it can get really tough to stay up-to date with the fast paced technologies around.
The frontend for Javascript is totally overwhelming with continuously upcoming frameworks and libraries. According to stateofjs.com statistics for 2018, about 64.8% of JS developers have used react for production followed by Vue 28.8% and then Angular 23.9%. But we still have another framework on the rise in 2019 Svelte which is slowly getting popular. However, the popularity of react is still many among the Javascript developers now and widely used till date.
So before we begin, you may question why we need Redux in React Application?
The answer would be you don’t need Redux in building your react application but you will soon know when u need them. As when the web application grows bigger it will be complex, to get with the task of updating and displaying their underlying data among various components. Developers may get totally frustrated in updating listeners and looking for change events which can later get much worse .
So, solution of the problem would be Redux — A single source of truth, a single state tree
What is Redux ?
Redux is a predictable state container for Javascript applications. Redux was created by Dan Abramov in 2015 to handle complex state management in an efficient way. It helps us writing applications that behave consistently, run in different environments are are much easier to test. Redux is simply a state management tool which tracks the changing state and reflects the changes in all components of our app using that particular state.
With the help of Redux, the state management for our Application is kept in a shared store from where each of our component can access the state and update the state when evoked.
How can we interact with the state?
Store is the single unit that holds the state tree. Each component can access the stored state without having to send down props from one component to another. There are three main parts:
actions, reducers and store.
Whereas, methods are the ones who interact with the state tree. The methods which are available to us to interact with the state are:
getState() It returns the current state of the application.
dispatch(action) It is only the way how our state is updated. Dispatching the action dispatch(action) does it for us.
subscribe(listener) It helps us to listen for the state when it changes. Every time a state is changed, it will invoke and returns us the updated state.
replaceReducer(nextReducer) It replaces the reducer currently used by the store for the calculation of the state.
Our main parts of the Store:
Actions:
Simply, actions are events in our application. It is the only way where we can send data from our application into the Redux store. The data can be from action from the user of events triggered from submitting a form.
Actions are actually plain javascript objects where they must have a type property to indicate the type of action that needs to be dispatched. Actions are sent using store.dispatch() method as mentioned earlier. They also need to have a payload that needs to be carried out to make the changes to the action event. Below is example of basic action which adds our todo’s:
/* adding initial state to our application */const initialState = {
todos: [],
type: []
};/* exporting our action types */export const ADD_TODO = 'ADD_TODO'/* action creators */export function addTodo(todo){
return {
type: "ADD_TODO",
todo: "frontend with JS frameworks"
}
}
Here in our code example we have initial state of our application where our data lives. We have defined our action ADD_TODO which can be imported and used inside other component. And lastly we have introduced a new term in the comments action creators. They simply are function which returns our actions with payload.
Reducers:
They are pure functions which takes up the current state of an application, perform an action and returns a new state to us. The states are stored as objects and they specify us how the state of our application changes in response to action sent by the action creators.
Note: Reducers takes the previous state of the app and return a new state based on the action passed to it.
function myreducer(state = initialState, action) {switch(action.type){
if (action.type === "ADD_TODO") {
return {
...state,
todos: [...state.todos, action.todo]
};
}
}
}
const store = createStore(myreducer);
It’s a pure function which do not change the data in the object passed neither any side effect in the application. Here in our example code we have created new reducer which is inside the switch case where the case is to empty to todo. If the case is to empty our array of todos, if not it returns us the default state value.
Store:
The store is the place where our application state lives. It is the place where our actions we created and reducers that updates the state comes together. There is just one store in any Redux application. With the help of methods; stores, update, register or unregister listeners via helper methods.
Lets create a store for our todo app:
const store = createStore(TodoComponent);
Lets also make our component how it looks like:
function Listing(todo) {
return (
<tr>
<td>{todo}</td>
</tr>
);
}function ourListing(todos) {
const rows = todos.map(row => Listing(row));
return <div>{rows}</div>;
}class Todo extends React.Component {
render() {
const { todos, posts } = store.getState();
return (
<div>
<ul>
<li>{ourListing(todos)}</li>
</ul>
<ul>
<li>{ourListing(posts)}</li>
</ul>
</div>
);
}
}
Here in the example code we accessed the list of todos which are inside our initial state todos array. Store generally have following properties:
- It holds the state of the application
- Helps us to dispatch actions and update state via dispatch(action);
- Allows access to state via getState();
- Registers listeners via subscribe(listener);
- Handles unregistering of listeners via the function returned by subscriber(listener)
Advantages of using Redux:
- Makes state predictable
- Scale the Application big
- Maintain and organized project
- Easy to debug
- Ease to test
Conclusion
Using redux in our application is really beneficial in long term as well. The benefits are countless. But sometimes your application don't may need state management, in such cases without redux application can still work well. Though its good to keep your frontend with a state management tool.
Following is the code from my code sandbox please feel free to fork and make your changes: