Understanding Redux with React
bhupendra
Posted on October 9, 2021
This is sequence of my earlier post about how to understand Redux in isolation and the problems it solves which cannot be solved by context API. To understand the importance of Redux in depth , here is an excellent article.
How to use React with Redux
Redux handles the store creation, middlewares & reducers logic. To use it with React, we need the instance of redux store for all components which is made available through Provider (using Context API). In Order to get the state and dispatch methods from the store we can use the connect from react-redux package. After Redux 7.0 we can use the useSelector and useDispatch hooks instead of wrapping our component with mapStateToProps and mapDispatchToProps.
Let's Build a React/Redux Project
We will continue building the project that was discussed in this post, but this time we will build the React UI also.
The project would have UI for two types of accounts: Current and Savings. There would also be a list of bank customers.
To get started we need to install below dependencies.
Here is how the directory structure of the project would look like:
In the previous , we have already seen how to setup action creators, reducers and combining reducers.
Here is how the redux store looks like now:
import { createStore, applyMiddleware } from "redux";
import { composeWithDevTools } from "redux-devtools-extension";
import thunk from "redux-thunk";
import logger from "redux-logger";
import rootReducer from "./rootReducer";
const store = createStore(
rootReducer,
composeWithDevTools(applyMiddleware(logger, thunk))
);
export default store;
Store instance would be passed down the components tree via Provider
import { Provider } from "react-redux";
import store from "./redux/store";
export default function App() {
return (
<Provider store={store}>
<div className="App">
...
</div>
</Provider>
);
}
To subscribe to the store we would be using useSelector hook and to get the dispatch function we would require useDispatch hook. Earlier connect
function was difficult to setup with Typescript but now these hooks provide easy TS integration.
export default CurrentAccounts = () => {
const amount = useSelector((state) => state.current.amount);
const dispatch = useDispatch();
return (
<div>
<label>Current Account</label>
<h3>{amount}</h3>
<div>
<button onClick={() => dispatch(withdrawMoneyCurrent())}>
Withdraw
</button>
<button onClick={() => dispatch(depositMoneyCurrent())}>Depoist</button>
</div>
</div>
);
};
Async Action Creator
We have used redux-thunk to call the dispatch function with actions in case of loading, success, error state for fetching data.
export const fetchCurrentUsers = () => {
return function (dispatch) {
dispatch(fetchStatusLoading);
axios
.get("https://jsonplaceholder.typicode.com/users")
.then((res) => {
const data = res.data.map((item) => ({ id: item.id, name: item.name }));
dispatch(fetchStatusSuccess(data));
})
.catch((error) => {
dispatch(fetchSatusError(error.message));
});
};
};
π Here is the complete sandbox to practice above concepts
And if you have Redux Dev Tools chrome extension , then you can replay the state transitions , dispatch custom functions and generate tests.
If you are using redux only to fetch data and save it to a centralized store then there is an another way to do it with more efficient cache performance and less code ~ Redux Query. Dan's blog on when not to use Redux is also a worth to read.
Posted on October 9, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.