joplin-notes/joplin notion extension/Web Development/React/Redux.md
2026-11-04 00:33:23 +05:30

123 lines
No EOL
3.9 KiB
Markdown

Redux
Sure, Redux is commonly used to manage state in complex React applications, avoiding the need to pass props deeply through nested components. Below is a simple example that illustrates how Redux can be used to share state between components without prop drilling.
Let's create a counter app where you can increase, decrease, and reset the count. We'll use three components: `App` (the parent component), `CounterDisplay` (to display the count), and `CounterControls` (to increase, decrease, or reset the count), showing how Redux allows them to communicate without passing props through each other directly.
### Step 1: Setup
First, ensure you have Redux and React-Redux installed in your project:
```bash
npm install redux react-redux
```
### Step 2: Create Redux Store, Reducer, and Actions
**store.js**
```javascript
import { createStore } from 'redux';
// Reducer function
function counterReducer(state = { count: 0 }, action) {
switch (action.type) {
case 'INCREMENT':
return { count: state.count + 1 };
case 'DECREMENT':
return { count: state.count - 1 };
case 'RESET':
return { count: 0 };
default:
return state;
}
}
// Create and export the store
export const store = createStore(counterReducer);
```
### Step 3: Setup Redux Provider
In your main entry file (like `index.js`), wrap your root component with the `Provider` from `react-redux` and pass the store to it:
**index.js**
```javascript
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { Provider } from 'react-redux';
import { store } from './store';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
```
### Step 4: Creating Components
**App.js** - The parent component
```javascript
import React from 'react';
import CounterDisplay from './CounterDisplay';
import CounterControls from './CounterControls';
function App() {
return (
<div>
<h1>Redux Counter Example</h1>
<CounterDisplay />
<CounterControls />
</div>
);
}
export default App;
```
**CounterDisplay.js** - Component to display the count
```javascript
import React from 'react';
import { useSelector } from 'react-redux';
function CounterDisplay() {
const count = useSelector(state => state.count); // Accessing count from Redux state
return <h2>Count: {count}</h2>;
}
export default CounterDisplay;
```
**CounterControls.js** - Component to control the count
```javascript
import React from 'react';
import { useDispatch } from 'react-redux';
function CounterControls() {
const dispatch = useDispatch(); // To dispatch actions
return (
<div>
<button onClick={() => dispatch({ type: 'INCREMENT' })}>Increase</button>
<button onClick={() => dispatch({ type: 'DECREMENT' })}>Decrease</button>
<button onClick={() => dispatch({ type: 'RESET' })}>Reset</button>
</div>
);
}
export default CounterControls;
```
### Brief Explanation
In this example:
- We've created a Redux store to hold our state, which in this case is simply a `count` value.
- The `counterReducer` handles actions (increment, decrement, reset) to update the state accordingly.
- The `App` component is our root component, rendering both the `CounterDisplay` and `CounterControls` components.
- The `CounterDisplay` component uses `useSelector` to read the `count` value from the Redux store directly, without needing to receive it as a prop.
- The `CounterControls` component uses `useDispatch` to dispatch actions that update the state, without needing to receive dispatch functions as props.
By using Redux, we've avoided the need to pass the `count` state or the dispatch functions through the `App` component, directly connecting the `CounterDisplay` and `CounterControls` components to the state they need. This simplifies the component structure and makes state management more efficient and scalable for larger applications.