React application without Redux and with Redux

Jaeyoung Kim
5 min readApr 11, 2021

This is the second article for React-Redux. (Previous article: https://jaeyoung-kim-dev.medium.com/what-is-a-redux-and-why-do-you-use-it-a3207ebad0e6)

I made a very simple application like below.

This application displays the value of GrandChild B by calculating the numbers previously stored in GrandChild B when the numbers are submitted in input in GrandChild A.

The structure of this application is below.

The first example is without Redux.

As you can see in the picture, adding the number 5 should go through all components from Grandchild A to B.

Let me show the code for this first and explain the application of Redux to drastically reduce this next time.

App.js: The root component of the application. It has currentValue state and passes them to each parent component.

import React, { useState } from 'react';
import './App.css';
import ParentA from './components/ParentA';
import ParentB from './components/ParentB';
function App() {
const [currentValue, setCurrentValue] = useState(0);
return (
<div className='App'>
<div className={'warapper parent'}>
<ParentA
currentValue={currentValue}
setCurrentValue={setCurrentValue}
/>
</div>
<br />
<div className={'warapper parent'}>
<ParentB currentValue={currentValue} />
</div>
</div>
);
}
export default App;

ParentA.js: It passes the props from the parent to the child component.

import React from 'react';
import ChildA from './ChildA';
function ParentA(props) {
return (
<div>
<h1>Parent A</h1>
<div className='warapper child'>
<ChildA
currentValue={props.currentValue}
setCurrentValue={props.setCurrentValue}
/>
</div>
</div>
);
}
export default ParentA;

ParentB.js: It passes the props from the parent to the child component.

import React from 'react';
import ChildB from './ChildB';
function ParentB(props) {
return (
<div>
<h1>Parent B</h1>
<div className='warapper child'>
<ChildB currentValue={props.currentValue} />
</div>
</div>
);
}
export default ParentB;

ChildA.js: It passes the props from the parent to the grandchild component.

import React from 'react';
import GrandChildA from './GrandChildA';
function ChildA(props) {
return (
<div>
<h1>Child A</h1>
<div className={'warapper grandchild'}>
<GrandChildA
currentValue={props.currentValue}
setCurrentValue={props.setCurrentValue}
/>
</div>
</div>
);
}
export default ChildA;

ChildB.js: It passes the props from the parent to the grandchild component.

import React from 'react';
import GrandChildB from './GrandChildB';
function ChildB(props) {
return (
<div>
<h1>Child B</h1>
<div className={'warapper grandchild'}>
<GrandChildB currentValue={props.currentValue} />
</div>
</div>
);
}
export default ChildB;

GrandChildA.js: It has a number input and a button to submit it. It sends the sum of the input value and the root’s currentValue back to the currentValue.

import React, { useState } from 'react';function GrandChildA(props) {
const [number, setNumber] = useState(0);
return (
<div>
<h1>GrandChild A</h1>
<input
type='number'
onChange={(e) => setNumber(parseInt(e.target.value))}
/>
<br />
<button
onClick={() => props.setCurrentValue(props.currentValue + number)}
>
Submit
</button>
</div>
);
}
export default GrandChildA;

GrandChildB: It displays the currentValue of the root.

import React from 'react';function GrandChildB(props) {
return (
<div>
<h1>GrandChild B</h1>
<h2>Current Value is {props.currentValue}</h2>
</div>
);
}
export default GrandChildB;

So far, we have looked at applications without Redux. This is a very simple structure, but it would be a very complex application if many child components and their structure were very deep.

Let’s change this to an application that applies Redux like below.

The state can be managed by simply sending and receiving desired values from the Redux store as shown in the picture above. Let’s check the codes below.

store.js: The most important thing in Redux application is the store. It stores the state commonly used in the application here.

import { createStore } from 'redux';
export default createStore(function (state, action) {
if (state === undefined) {
return { currentNumber: 0 };
}
if (action.type === 'CHANGE_VALUE') {
return { ...state, currentNumber: state.currentNumber + action.size };
}
return state;
}, window.__REDUX_DEVTOOLS_EXTENSION__ &&
window.__REDUX_DEVTOOLS_EXTENSION__());

App.js: It applied Provider from the Redux package and provided store.js here.

import React from 'react';
import './App.css';
import { Provider } from 'react-redux';
import store from './store';
import ParentA from './components/ParentA';
import ParentB from './components/ParentB';
function App() {
return (
<Provider store={store}>
<div className='App'>
<div className={'warapper parent'}>
<ParentA />
</div>
<br />
<div className={'warapper parent'}>
<ParentB />
</div>
</div>
</Provider>
);
}
export default App;

ParentA.js: It used to pass the props from the parent to the child component. But not anymore! You can simply delete the props.

import React from 'react';
import ChildA from './ChildA';
function ParentA(props) {
return (
<div>
<h1>Parent A</h1>
<div className='warapper child'>
<ChildA />
</div>
</div>
);
}
export default ParentA;

ParentB.js: Just like ParentA, delete all props.

import React from 'react';
import ChildB from './ChildB';
function ParentB(props) {
return (
<div>
<h1>Parent B</h1>
<div className='warapper child'>
<ChildB />
</div>
</div>
);
}
export default ParentB;

ChildA.js: The same. Delete all props.

import React from 'react';
import GrandChildA from './GrandChildA';
function ChildA() {
return (
<div>
<h1>Child A</h1>
<div className={'warapper grandchild'}>
<GrandChildA />
</div>
</div>
);
}
export default ChildA;

ChildB.js: The same. Delete all props.

import React from 'react';
import GrandChildB from './GrandChildB';
function ChildB(props) {
return (
<div>
<h1>Child B</h1>
<div className={'warapper grandchild'}>
<GrandChildB />
</div>
</div>
);
}
export default ChildB;

GrandChildA.js: The mapDispatchToProps function below communicates the number you want to add or subtract along with CHANGE_VALUE payload to the store. And put the GrandChildA component through the bottom ‘connect’.

import React, { useState } from 'react';
import { connect } from 'react-redux';
function GrandChildA(props) {
const [number, setNumber] = useState(0);
return (
<div>
<h1>GrandChild A</h1>
<input
type='number'
onChange={(e) => setNumber(parseInt(e.target.value))}
/>
<br />
<button onClick={() => props.onClick(number)}>Submit</button>
</div>
);
}
const mapDispatchToProps = (dispatch) => {
return {
onClick: (number) => dispatch({ type: 'CHANGE_VALUE', size: number }),
};
};
export default connect(null, mapDispatchToProps)(GrandChildA);

GrandChildB.js: Receive and display the currentNumber from the store through the mapStateToProp function.

import React from 'react';
import { connect } from 'react-redux';
function GrandChildB(props) {
return (
<div>
<h1>GrandChild B</h1>
<h2>Current Value is {props.currentNumber}</h2>
</div>
);
}
const mapStateToProp = (state) => ({
currentNumber: state.currentNumber,
});
export default connect(mapStateToProp)(GrandChildB);

Conclusion

In my opinion, Redux is not an easy technology, and many code examples may make it difficult to understand. However, the use of Redux simplifies code and makes state management easier. I hope my video added below will help you understand. The video also contains additional tips not described in the blog.

Source Code: https://github.com/Jaeyoung-Kim-Dev/React-Redux-Blog-Example.git

--

--