Redux is a framework that controls states in
a JavaScript app. According to the official site:
“Redux is a predictable state container for
JavaScript apps.”
Learning a new JavaScript framework in 2017
can be a daunting task. I find the article to be one of the most helpful
tutorials out there. It can still be too much for someone starting out in
React/Redux so I documented my journey.
Demystifying Redux
To start with
Redux, let’s see various component for Redux
- Store
- Reducers
- Provider
- Containers
- Components
- Actions
Store: Manages the states. Mainly there is a
dispatch method to dispatch an action. In a Redux app, you can obtain its
states via store.getState()
Reducers: Reducers take in actions and update part of
application state.
·
We combine
all reducers into a single object before updated data is dispatched (sent) to
store
·
Your entire
applications state (store) is just whatever gets returned from all your
reducers
Provider: it connected state and application
components
Components: Containers are very similar to components, the only difference is that
containers are aware of application state. If part of your webpage is only used
for displaying data (dumb) then make it a component. If you need it to be smart
and aware of the state i.e. whenever data changes system become aware
Containers: Containers
fetch state data and use it to render (display) components.state data
will become components props
Containers
are similar to components. However, only containers have access to state data
in Redux.components
are sometimes called "dumb components" or "presentational
components"
Actions: A simple, plain
JavaScript Object. An action can also be considered as a command
to change a state.
Redux Example
Let’s make an
example application which will list down users and selection on any user will
show its details. Application data flow is as follows
I have used JetBrains
“WebStorm 2017.2.5” IDE for making learning sample, latest Node JS and step one
is to build page which will list down users say index.html
index.html
<!DOCTYPE html>
<html lang="en"><head> <meta charset="UTF-8"> <title>React Webpack</title></head><body> <div id="root"></div> <script src="js/bundle.min.js"></script></body></html>
Root is main
container which will hold all application components i.e. display or render dynamic
page then let’s create file structure for our sample application, as shown in
below snapshot
We will be
creating #1 component, which will list down #2 different type of data , which
is we are referring as reducers one is collection of user then another is
details of select users. Obviously action is user selection. Let’s club all
this together build First components, its list down all dynamic HTML part of
our application so App.js will be as follows
import
React from 'react';
import UserList from '../containers/user-list';
import UserDetail from '../containers/user-detail';
require(
require('../../scss/style.scss');
const App = () => (
<
<div>
<h2>User List:</h2>
<UserList/>
<hr />
<h2>User Details:</h2>
<UserDetail/>
</div>
);
export default App;
Where App is main component and user
list and user details are reducers. Then let’s
create reducers index.js, it will hold all reducers of application into one place.
In our case where we want to build user list and show user information it will
have two reducers’ reducer-users.js
& reducer-active-user.js
index.js
import
{combineReducers}
from 'redux';
import UserReducer from './reducer-users';
import ActiveUserReducer from './reducer-active-user';
const allReducers = combineReducers({
users: UserReducer,
activeUser : ActiveUserReducer
});
});
export default allReducers;
So
allReducers is main reducer which holds reference of user reducer and Active User
reducer. reducer-users.js & reducer-active-user.js
are as follows
export default function () {
return [
{
{
id: 1,
first: "Manjul",
last: "Dube",
age: 71,
description: "Manjul Dube",
thumbnail: "http://lh5.googleusercontent.com/s80-c/photo.jpg"
},
] reducer-active-user.js export
default function (state=null, action) {
switch(action.type){
case "USER_SELECTED":
return
action.payload;
break;
}
}
return state;
}
}
reducer-active-user.js
is important to focus as here we have defined action type user selected , it’s
doing nothing special just define action call back method.. Action object hold
two parts, first is description which say what is performed and second is
result of action, so in action index.js will look as follows
index.js
export
const selectUser = (user) => {
console.log("You clicked on user: ", user.first);
return {
type: 'USER_SELECTED',
payload: user
}
};
So till now basic skeleton is ready,
now we need to make containers, they will connect our application state to its
component and make them smart state aware parts. Container hold following two
important methods mapStateToProps & matchDispatchToProps.. So user-list.js
container will look as follows
user-list.js
import React, {Component} from 'react';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import {selectUser} from '../actions/index'
class UserList extends Component {
createListItems(){
return this.props.users.map(
user => {
user => {
return (
<
<li
key={user.id}
onClick={ () => this.props.selectUser(user)}
> {user.
> {user.first} {user.last}
</
</li>
); }
); } render() {
return (
<
<ul>
{this.createListItems()}
</
</ul>
);
}}function mapStateToProps(state){
return {
users : state.users
}
}
}
}
function matchDispatchToProps(dispatch){
return bindActionCreators({selectUser: selectUser}, dispatch);
}
}
export default connect(mapStateToProps ,matchDispatchToProps)(UserList);
user-detail.js
import React, {Component} from 'react';
import {connect} from 'react-redux';
class UserDetail extends Component {
render() {
if (!this.props.user) {
return (<div>Select a user...</div>);
}
}
return (
<
<div>
<img src={this.props.user.thumbnail} height="150px;" width="230px;" />
<h2>{this.props.user.first} {this.props.user.last}</h2>
<h3>Age: {this.props.user.age}</h3>
<h3>Description: {this.props.user.description}</h3>
</div>
);
}
}function mapStateToProps(state) {
return {
user: state.activeUser
};
}
};
}
export default connect(mapStateToProps)(UserDetail);
Once application is ready, run npm
start command that will run your application
If select any user it will give you
following result
My goal was simple to understand
Redux and manage state, I follow a boilerplate application and created
something similar. Though its SPA and just learning sample but consist of all
technical components and their interaction. it’s a beginner’s Travel Log, I stared with various blogs, tutorials and downloaded one of boilerplate from GitHub to go through Redux. What do you think? Let me know your
inputs and questions that will lead another direction for learning and exploration..
Courtesy: Several online blogs, you tube videos, tutorials,GitHub sample code & other resources
Hi there,I enjoy reading through your article post. Thank you for sharing.
ReplyDeleteMern stack training in hyderabad