what is redux?
Redux is an open-source JavaScript library for managing and centralizing application state. It is most commonly used with libraries such as React or Angular for building user interfaces
but I hope I could understand this in an easy way
React applications build with various components and when we want to communicate between two components on events onClick, onHover e.t.c. for transferring the data between two components then that time it's ok to use props but when apps containing a lot of components then there will be a long hierarchy for transferring the data from one component to the other component then it's become hectic to manage the whole app.
To overcome this problem redux is introduced. In redux, the whole state of the app is in store.js file and we can use and manipulate state as our requirements
why redux-toolkit?
I remember the first time I was implementing the react-redux. react-redux has complex boilerplate code and it's overwhelming to remember all those steps to overcome some unnecessary and time-consuming code snippets react-react-toolkit was created. this is nothing but one one-step wrap on react-redux
Redux-flow :
here is the pictorial diagram of how redux flow is executed
Let's understand the redux toolkit by the practical app (counter app)
first, we have to set up the redux toolkit. for installing the redux toolkit use this command
npm install @reduxjs/toolkit
the directory structure will look like this (this is just a demo project you can refactor the code further)
at first in store.js write this piece of code
import { configureStore } from '@reduxjs/toolkit';
export default configureStore({
reducer: {
//all reducer will be here
},
});
then we will define reducer in src/app/features/counter/counterslice.js directory
import { createSlice } from '@reduxjs/toolkit';
export const slice = createSlice({
name: 'counter',
initialState: {
value: 0,
},
reducers: {
increment: state => {
// Redux Toolkit allows us to write "mutating" logic in reducers. It
// doesn't actually mutate the state because it uses the immer library,
// which detects changes to a "draft state" and produces a brand new
// immutable state based off those changes
state.value += 1;
},
decrement: state => {
state.value -= 1;
},
incrementByAmount: (state, action) => {
state.value += action.payload;
},
},
});
export const { increment, decrement, incrementByAmount } = slice.actions;
// The function below is called a thunk and allows us to perform async logic. It
// can be dispatched like a regular action: `dispatch(incrementAsync(10))`. This
// will call the thunk with the `dispatch` function as the first argument. Async
// code can then be executed and other actions can be dispatched
export const incrementAsync = amount => dispatch => {
setTimeout(() => {
dispatch(incrementByAmount(amount));
}, 1000);
};
// The function below is called a selector and allows us to select a value from
// the state. Selectors can also be defined inline where they're used instead of
// in the slice file. For example: `useSelector((state) => state.counter.value)`
export const selectCount = state => state.counter.value;
export default slice.reducer;
In this file we just define reducers now let's see how to trigger this reducer from the UI
create file src/app/features/counter/counter.js
import React, { useState } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import {
decrement,
increment,
incrementByAmount,
incrementAsync,
selectCount,
} from './counterSlice';
import styles from './Counter.module.css';
export function Counter() {
const count = useSelector(selectCount);
const dispatch = useDispatch();
const [incrementAmount, setIncrementAmount] = useState('2');
console.log(count,"count")
return (
<div>
<div className={styles.row}>
<button
className={styles.button}
aria-label="Increment value"
onClick={() => dispatch(increment())}
>
+
</button>
<span className={styles.value}>{count}</span>
<button
className={styles.button}
aria-label="Decrement value"
onClick={() => dispatch(decrement())}
>
-
</button>
</div>
<div className={styles.row}>
<input
className={styles.textbox}
aria-label="Set increment amount"
value={incrementAmount}
onChange={e => setIncrementAmount(e.target.value)}
/>
<button
className={styles.button}
onClick={() =>
dispatch(incrementByAmount(Number(incrementAmount) || 0))
}
>
Add Amount
</button>
<button
className={styles.asyncButton}
onClick={() => dispatch(incrementAsync(Number(incrementAmount) || 0))}
>
Add Async
</button>
</div>
</div>
);
}
our UI is set you can visit this link for the source code
Additional tips
can get useSelector hook for getting state.
useDispatch hook for triggering actions and update the state
thank you !
let's connect over github