React Redux

Lawson Hung
3 min readMay 29, 2020

--

Redux is an organized way to manage your state. React has its own redux library for managing state. A barebones React app has each of its components managing state, and passes it down to each component as props. However, this can get messy and disorganized as your app grows. Hitherto, Redux to the rescue!

First, we have to install regular Redux:

$ npm install redux

We also have to install React’s redux as well:

$ npm install react-redux

Now in your React app, we need to import the libraries:

// index.jsimport { createStore } from 'redux';import { Provider } from 'react-redux';

With the createStore function, we can create a regular redux store:

// index.js
const lawsonsStore = createStore(rootReducer);

rootReducer is an object for storing state, the main source of truth for the store. We’ll have to create it. First, let’s write the import line:

// index.js
import rootReducer from './reducers/rootReducer';

We also have to wrap the App component in Provider:

ReactDOM.render(<Provider store={lawsonsStore}><App /></Provider>,document.getElementById('root'));

Note that Redux actually does NOT persist on a page refresh, so we’ll use a library call redux-persist for the future.

Going back to our root reducer, we have to make a folder called reducers and in there, make a file called rootReducer.js to create the path file ./reducer/rootReducer. In there, I have the following:

// ./reducers/rootReducer.js
export default (state={
username: ''}, action) => {switch (action.type) {case 'STORE_USERNAME':return {username: action.username}case 'CLEAR_USERNAME':return {username: ''}default:return state;}}

When you want to update the store, you always need an Object with the key type. This type key tells the store what you want to do or how you want to update the store.

Now that we have things set up, we have to connect to the store first to update it and to read from it.

Let’s say I have a Login page for the user to log in. I have to import the connect function first:

// LoginPage.js
import { connect } from 'react-redux';

On the bottom of the page where we export the component:

// LoginPage.js
export default connect(mapStateToProps, mapDispatchToProps)(LoginPage)

This allows us to have access to the store.

We have to make LoginPage accessible variables.

const mapStateToProps = (store) => {return {username: store.username}}const mapDispatchToProps = (dispatch) => {return {storeUsernameToRedux: (username) => {dispatch({ type: 'STORE_USERNAME', username: username})}}}

Updating the store is called dispatching to the store. You define a function, I named mine storeUsernameToRedux and you pass in the new username as an argument. In your code, whenever you want to update the username, you do:

handleUsernameChange = (e) => {this.props.storeUsernameToRedux(e.target.value);}

Here is the full file for reference:

// LoginPage.js
import React, { Component } from 'react';
import { connect } from 'react-redux';class LoginPage extends Component {state = {password: ''}handleChange = (e) => {// this.setState({[e.target.name]: e.target.value});}handleUsernameChange = (e) => {this.props.storeUsernameToRedux(e.target.value);}handlePasswordChange = (e) => {this.setState({ [e.target.name]: e.target.value });}handleSubmit = (e) => {e.preventDefault();// Local fetch// fetch('http://localhost:3000/login', {// Heroku fetchfetch('https://perfect-desserts-2-backend.herokuapp.com/login', {method: 'POST',headers: {'Accept': 'application/json','Content-Type': 'application/json'},body: JSON.stringify({'username': this.props.username,'password': this.state.password})}).then(res => res.json()).then(data => {if (data.token) {this.props.storeToken(data.token);this.props.storeUsername();this.props.routerProps.history.push('/profile');}});}handleClick = () => {this.props.routerProps.history.push('/signup');}render() {console.log("Login props: ", this.props);console.log('Login state: ', this.state);return (<div><h1>Log in please!</h1><form onSubmit={this.handleSubmit}><input onChange={this.handleUsernameChange} value={this.props.username} type="text" name="username"/><input onChange={this.handlePasswordChange} value={this.state.password} type="password" name="password"/><input type="submit" value="Log in" /></form><button onClick={this.handleClick}>Don't have an account yet? Click here to create one</button></div>);}}const mapStateToProps = (store) => {return {username: store.username,token: store.token}}const mapDispatchToProps = (dispatch) => {return {storeToken: (token) => {dispatch({ type: 'STORE_TOKEN', token: token })},storeUsernameToRedux: (username) => {dispatch({ type: 'STORE_USERNAME', username: username})}}}export default connect(mapStateToProps, mapDispatchToProps)(LoginPage)

You’ll notice that I have a token that I’m passing in to my server. I’m also using BrowserRouter for routing between pages in my app.

Stay safe!

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Lawson Hung
Lawson Hung

No responses yet