123 lines
No EOL
3.9 KiB
Markdown
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. |