3.9 KiB
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:
npm install redux react-redux
Step 2: Create Redux Store, Reducer, and Actions
store.js
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
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
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
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
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
countvalue. - The
counterReducerhandles actions (increment, decrement, reset) to update the state accordingly. - The
Appcomponent is our root component, rendering both theCounterDisplayandCounterControlscomponents. - The
CounterDisplaycomponent usesuseSelectorto read thecountvalue from the Redux store directly, without needing to receive it as a prop. - The
CounterControlscomponent usesuseDispatchto 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.