Show pageBacklinksBack to top This page is read only. You can view the source, but not change it. Ask your administrator if you think this is wrong. ====== Redux ====== - Install redux, react-redux, and update the react-dom - Create a reducer for storing the state, and handle the dispatched task - Create the store in index.js, and provide it to the app by <Provider...></Provider> - Using redux in your component: - Class-based component: In your component, create mapStateToProps, and mapDispatchToProps. Then use import {connect} from 'react-redux'; to connect your component to the store. - Functional-based component: Use {useSelector, useDispatch} from 'react-redux'. ''useSelector'' obtains the values, and ''useDispatch'' dispatches the actions. ===== Install ===== <code> npm install react react-redux npm update react react-dom </code> ===== Create Reducer ===== create a file call ''reducer.js'', put in under /src/store/. We also put the initial state there. <code> const initialState = { counter: 0 } const reducer = (state = initialState, action) => { switch (action.type) { case 'INCREMENT': return { ...state, counter: state.counter + 1 } case 'DECREMENT': return { ...state, counter: state.counter - 1 } case 'INCREMENT5': return { ...state, counter: state.counter + action.value } case 'DECREMENT5': return { ...state, counter: state.counter - action.value } default: return state; } } export default reducer; </code> ===== Create Store in index.js, and Provider it to the app ===== Here we create the store by using createStore, passing out reducer to it. Finally provide it to the app by <Provider store={...}...></Provider> <code> import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; import registerServiceWorker from './registerServiceWorker'; import {createStore} from "redux"; import reducer from "./store/reducer"; import {Provider} from 'react-redux'; const store = createStore(reducer); ReactDOM.render( <Provider store={store}> <App/> </Provider>, document.getElementById('root')); registerServiceWorker(); </code> ===== Connect Out Component to it ===== ==== Old Way: For Class Base Component ==== The key here is to create a ''mapStateToProps'' to get the state from redux, and a ''mapDispatchToProps'' to dispatch actions to the redux. We connect redux to our component by using export default connect(mapStateToProps, mapDispatchToProps)(Counter); at the end. Since the state and action are now the props, we can use them and call them in our component like ''this.props...''. The 'action' we dispatch usual has a ''type'' for the type of action, and any addition fields if needed. <code> import React, {Component} from 'react'; import CounterControl from '../../components/CounterControl/CounterControl'; import CounterOutput from '../../components/CounterOutput/CounterOutput'; import {connect} from 'react-redux'; class Counter extends Component { render() { return ( <div> <CounterOutput value={this.props.ctr}/> <CounterControl label="Increment" clicked={this.props.onIncrementCount}/> <CounterControl label="Decrement" clicked={() => this.props.onDecrementCount()}/> <CounterControl label="Add 5" clicked={() => this.props.onInc5Count()}/> <CounterControl label="Subtract 5" clicked={() => this.props.onDec5Count()}/> </div> ); } } const mapStateToProps = state => { return { ctr: state.counter } }; const mapDispatchToProps = dispatch => { return { onIncrementCount: () => dispatch({type: 'INCREMENT'}), onDecrementCount: () => dispatch({type: 'DECREMENT'}), onInc5Count: () => dispatch({type: 'INCREMENT5', value:5}), onDec5Count: () => dispatch({type: 'DECREMENT5', value:10}), }; } export default connect(mapStateToProps, mapDispatchToProps)(Counter); </code> The action.type needs to match the one in the reducer! Any spelling mistake/mismatch would cause the reducer to do nothing. You might want to use a separated file, and include this file on both the reducer and the component. ==== New Way: Use Hooks For Functional Base Component ==== People in these days use functional base component for react, and here is how to use redux in it by using ''useSelector'', ''useDispatch'' and hooks. <code> import './App.css'; import {useSelector, useDispatch} from 'react-redux' function App() { const count = useSelector(state => { return state.counter; } ) const dispatch = useDispatch(); const click = (action, value) => { if (value) { dispatch({type: action, value: value}); } else { dispatch({type: action}); } } return ( <> <div>The counter is: {count}</div> <button onClick={() => click('INCREMENT')}>INCREMENT</button> <button onClick={() => click('DECREMENT')}>DECREMENT</button> <button onClick={() => click('INCREMENT5', 5)}>INCREMENT 5</button> <button onClick={() => click('DECREMENT5', 5)}>DECREMENT 5</button> </> ) } export default App; </code> reject/redux.txt Last modified: 2021/09/29 17:17by chongtin