Context is used in the class component

1. Create context context

// utils.js
import React, {createContext} from 'react'
const MoneyContext = createContext()  // Create context
export default MoneyContext  / / export MoneyContext
Copy the code

2. Parent component

import React, { Component } from 'react';
import Child from './child'
import MoneyContext from '.. /utils/Context'

export default class Parent extends Component {
    // Set the initial state of money
    state ={ 
        money: 100
    }
    // Define a method to modify its state
    setMoney = (newMoney) = >{
        this.setState({
            money: newMoney
        })
    }
    render() {
        return (
            <MoneyContext.Provider value={{money: this.state.money.setMoney:this.setMoney}} >
                <div>
                    <h3>Parent component ---- parent</h3>
                    <Child></Child>
                </div>
            </MoneyContext.Provider>)}}Copy the code

In the parent component: Wrap the parent component with moneyContext.provider and add the value attribute to pass the state and method to descendant component calls.

3. Subcomponents

import React, { Component } from 'react';
import GrandChild from './grandChild'
import MoneyContext from '.. /utils/Context'

export default class Child extends Component {
    static contextType = MoneyContext
    // This method receives properties passed by the parent component, which can be used in other life cycles
	
    constructor(props, context) {
        console.log('11',context);
        super(a)this.state = {
            money1: context.money
        }
    }+
    componentDidMount() {
        console.log(this.context.money)
        /* After the component is mounted, use the value of the MyContext component to perform some side effects */
    }
    
    componentDidUpdate(props, context){
        console.log(this.context);
       
    }
    componentWillUnmount() {
        let value = this.context;
    }
    render() {
        return (
            <div>
                <h3>Child component ----- child</h3>
                <p>The value passed by the parent component ----{this.context.money}</p>
                <GrandChild></GrandChild>
            </div>)}}Copy the code

Using static contextType = MoneyContext, which receives the value passed by the parent component, you can perform side effects in other lifecycle functions. The contextType property mounted on the class is reassigned to a Context object created by react.createcontext (). This allows you to use this.context to consume the value of the most recent context. You can access it in any lifecycle, including the Render function.

4. Sun Tzu components

import React, { Component } from 'react';
import MoneyContext from '.. /utils/Context'

export default class GrandChild extends Component {

    render() {
        return (
            // Can only be used in render functions, not other life cycle numbers
            <MoneyContext.Consumer>
                        {
                            value => {
                                return (
                                    <div>
                                        <h3>GrandChild component ---- grandChild</h3>
                                        <p>The value passed by the parent component ---- {value.money}</p>
                                        <button onClick={()= >Value. SetMoney (200)} > don't have enough money</button>
                                    </div>)}}</MoneyContext.Consumer>)}}Copy the code

The component is wrapped with the moneyContext.consumer tag and internally retrieves the state and methods passed by the parent component in the form of functions. Because you subscribe to the context as a Consumer, you can only access the methods and state passed by the parent in Render. Therefore, it is best to subscribe to the context as a function component. According to the website:

A React component can subscribe to changes to a context, which allows you to subscribe to a context in a functional component. This method requires a function as a child. This function takes the current context value and returns a React node. The value passed to the function is equivalent to the value provided by the Provider at the top of the component tree closest to the context. If there is no Provider, the value argument is equivalent to the defaultValue passed to createContext().Copy the code

Use context, useState in function components

Using context in a function component is basically the same as using context in a class component

1. Create context context

// utils.js
import React, {createContext} from 'react'
const MoneyContext = createContext()  // Create context
export default MoneyContext  / / export MoneyContext
Copy the code

2. Parent component

import React, { useState } from 'react';
import Child from './child'
import MoneyContext from '.. /utils/Context'

const Parent = () = > {
    // Create the money state with useState and initialize it
    let [money, setMoney] = useState(10)
    return (
        <MoneyContext.Provider value={{money: money}} >
            <div>
                <h3>Function component parent component</h3>
                <button onClick={()= >SetMoney} > modify the money (money = 100)</button>
                <hr/>
                <Child></Child>
            </div>
        </MoneyContext.Provider>
    );
}

export default Parent;
Copy the code

3. Subcomponents

import React from 'react';
import GrandChild from './grandChild'
import MoneyContext from '.. /utils/Context'

function Child() {
    return (
        <MoneyContext.Consumer>
            { 
                value => {
                    return (                
                        <div>
                            <h3>Function component subcomponents</h3>
                             <p>Money :{value[0]}----age:{value[1]}</p>
                            <hr/>
                            <GrandChild></GrandChild>
                        </div>)}}</MoneyContext.Consumer>)}export default Child
Copy the code

4. Sun Tzu components

import React from 'react';
import MoneyContext from '.. /utils/Context'

const GrandChild = () = > {
    return (
        <div>
            <h3>Function component grandson component</h3>
        </div>
    );
}

export default GrandChild;
Copy the code

Function components useContext, useContext, and useReducer for state management

1. Create context context

import React, {createContext} from 'react'
const MoneyContext = createContext()
export default MoneyContext
Copy the code

2. Create reducer

// Handle the reducer of money
const moneyReducer = (state, action) = > {
    switch (action.type) {
        case 'ADD':
            return state + 10;
        case 'SUB':
            return state - 10;
        default:
            returnstate; }}// Handle the reducer of age
const ageReducer = (state, action) = > {
    switch (action.type) {
        case 'ADD':
            return state + 1;
        case 'SUB':
            return state - 1;
        default:
            returnstate; }}export {
    moneyReducer,
    ageReducer
}
Copy the code

Parent component

import React, { useReducer } from 'react';
import Child from './child'
import MoneyContext from '.. /utils/Context'

import { moneyReducer, ageReducer } from './reducer'

const Parent = () = > {
    // Initialize the money state, specify the reducer handler, and send dispatch that triggers the reducer function
    let [money, moneyDispatch] = useReducer(moneyReducer, 10)
    let [age, ageDispatch] = useReducer(ageReducer, 15)
    return (
        <MoneyContext.Provider value={[money, age.moneyDispatch.ageDispatch]} >
            <div>
                <h3>Function component parent component</h3>
                <button onClick={()= >MoneyDispatch ({type: 'ADD'})}> Modify money</button>
                <hr/>
                <Child></Child>
            </div>
        </MoneyContext.Provider>  

    );
}

export default Parent;
Copy the code

useReducer

The useReducer accepts two arguments:

The first parameter is the Reducer function and the second parameter is the state of the initialization. The return values are the latest state and dispatch functions (used to send actions that trigger the Reducer function to calculate the corresponding state).

According to the official website:

UseReducer can be more useful than useState in some situations, such as when the state logic is complex and contains multiple subvalues, or when the next state depends on the previous state. Also, using useReducer can optimize performance for components that trigger deep updates because you can pass dispatches to child components instead of callbacks.Copy the code

4. Subcomponents

import React from 'react';
import GrandChild from './grandChild'
import MoneyContext from '.. /utils/Context'

function Child() {
    return (
        <MoneyContext.Consumer>
            { 
                value => {
                    return (                
                        <div>
                            <h3>Function component subcomponents</h3>
                             <p>Money :{value[0]}----age:{value[1]}</p>// Call the moneyDispatch passed by the parent component to reduce the value of money<button onClick={()= >{value[2]({type:"SUB"})}}</button>
                            <hr/>
                            <GrandChild></GrandChild>
                        </div>)}}</MoneyContext.Consumer>)}export default Child

Copy the code

Receive the state and methods passed by the parent component — method one

Using the moneyContext.consumer tag, internally receive the state passed by the parent as a function (money…). And the method (moneyDispatch)

5, grandson components

import React, { useContext } from 'react';
import MoneyContext from '.. /utils/Context'

const GrandChild = () = > {
    const [money,age, moneyDispatch,ageDispatch] = useContext(MoneyContext);

    return (
        <div>
            <h3>Function component grandson component</h3>
            <p>Value passed by the parent component -- {money} -- {age}</p>// call the ageDispatch method to trigger the reducer make age++<button onClick={()= >AgeDispatch ({type: 'ADD'})}> Grandson grew up</button>
        </div>
    );
}

export default GrandChild;

Copy the code

Receive the state and methods passed by the parent component — method two

Use useContext to read the value of the context and subscribe to changes in the context.

UseContext () takes a context object (the return value of react.createcontext) and returns the current value of that context. The current context value is determined by the value in the < moneyContext.provider > of the upper-layer component closest to the current component. When the most recent < moneyContext.provider > update from the upper layer is made, the Hook triggers a re-rendering and uses the latest context value value. Rerender even if the ancestor used React. Memo or shouldComponentUpdate.

prompt

UseContext (MyContext) is equivalent to static contextType = MyConntext or

in the class component

Redux State Management – The todoList case

1, the action

// action/index.js
import store from '.. /store'

const ADD_TODO_ITEM = "ADD_TODO_ITEM"
const UPDATE_CHECKED = 'UPDATE_CHECKED'
const DELETE_USER = 'DELETE_USER'
const action = {
    addItem : (userInfo) = > {
        const action =  {
            type: ADD_TODO_ITEM,
            userInfo
        }
        store.dispatch(action)
    },
    updatedChecked: (id) = > {
        const action = {
            type: UPDATE_CHECKED,
            id
        }
        store.dispatch(action)
    },
    deleteUser: (id) = > {
        const action = {
            type: DELETE_USER,
            id
        }
        store.dispatch(action)
    }
}

export default action
Copy the code

Create an Action object and send the action through the Dispatch method provided by the Store. Encapsulate it as a function that the component calls directly (action.additem (), etc.).

2, reducer,

// reducer/index.js
const toDoList = [
    {id: 1.username: 'Zhu Yuanzhang'.position: 'Ming Tai Zu'.isChecked: true},
    {id: 2.username: 'Chu Yunwen'.position: 'Emperor Jianwen'.isChecked: false},]const reducer = (state = toDoList, action) = > {
    switch (action.type) {
        case 'ADD_TODO_ITEM':
            return handler.addItem(state,action.userInfo)
        case 'UPDATE_CHECKED':
            return handler.updateChecked(state, action.id)
        case 'DELETE_USER':
            return handler.deleteUser(state, action.id)

        default:
            return state
    }
}

const handler = {
    addItem: (arr,userInfo) = > {
        const newArr = arr.slice()
        userInfo = Object.assign(userInfo, {id: arr.length + 1})
        newArr.push(userInfo)
        return newArr
    },
    updateChecked: (arr, id) = > {
        const newArr = arr.slice()
        // Copy a new array and assign it to newArr to manipulate the new array.
        // If there is another array in the arR array, the state will change without changing the address of the ARR array. This is the case in React-Redux: React-Redux internally assumes that the address of the ARR has not changed and does not re-render the component (treating it as if state had not changed).
        for(let i=0; i<newArr.length; i++){if(newArr[i].id === id){ newArr[i].isChecked = ! newArr[i].isChecked } }return newArr
    },
    deleteUser: (arr, id) = > {
        return arr.filter(item= > {
            return item.id === id ? false : true}}})export default reducer
Copy the code

Reducer () is a function that receives two parameters: a previous state and an action. The body of the function performs different operations by determining the value of action.type.

3, store

// store/index.js
import { createStore } from 'redux'
import reducer from '.. /reducer'
const store = createStore(reducer)
export default store
Copy the code

Create a store repository and specify the corresponding reducer() handler

4. Home component

// pages/Home.jsx
import React, { Component } from 'react';
import List from '.. /components/List'
import action from '.. /action/index'
export default class Home extends Component {
    state = {
        userInfo: {
            username: ' '.position:' ',
        }
    }
    getUserInfo = (e) = > {
        // Collect the values in the input box
        let userInfo = Object.assign(this.state.userInfo, {[e.target.id]: e.target.value})
        this.setState({
            userInfo
        })
    }
   
    submit = () = > {
        // Call the function to send the action and add the user
        action.addItem(this.state.userInfo)
        this.setState({  // Empty the input field
            userInfo: {
                username: ' '.position:' ',}})}render() {
        return (
            <div>
                username: <input type="text" id="username" value={this.state.userInfo.username} onChange={this.getUserInfo}/> 
                position: <input type="text" id="position" value={this.state.userInfo.position} onChange={this.getUserInfo}/>
                <button onClick={this.submit}>submit</button>
                <List></List>// Call the List component to render the List</div>)}}Copy the code

5. List components

// components/List.jsx

import React, { Component, useState } from 'react';
import store from '.. /store'
import action from '.. /action'

// Define a function component that generates the li tag for each item in the list
const Item = (props) = > {
    const [liStyle, setLiStyle] = useState({
        color: 'springgreen',})// Modify the status of the check box to modify the isChecked property of the current user
    const updatedChecked = (e) = > {
        action.updatedChecked(e.target.parentNode.id*1)}// Call the function to delete the user
    const deleteUser = (e) = > {
        action.deleteUser(e.target.parentNode.id*1)}return <li style={props.item.isChecked ? liStyle : {}}  id={props.item.id}>
             <input type="checkbox" checked={props.item.isChecked} onChange={updatedChecked}/>
             {props.item.username} ---- {props.item.position} 
             <button onClick={deleteUser}>Delete user</button>
          </li>
}

export default class List extends Component {
    
    componentDidMount() {
        // Call the store.subscribe() method to listen for state changes in the Reducer function
        store.subscribe(() = > {
            // const updatedData = store.getState()
            this.setState({})  // Force the component to re-render by setting an empty object})}render() {
        return (
            <div>
                <ul>
                    {
                        store.getState().map((item) => {
                        return <Item item={item} key={item.id}/>})}</ul>
            </div>)}}Copy the code

React – Redux state Management-Todolist case

React-redux divides all components into two parts: a UI component (Presentational Component) and a container Component (Container Component).

Characteristics of UI components (user-defined components) :

  • Only responsible for the presentation of the UI, without any business logic
  • No state (that is, the this.state variable is not used)
  • All data is provided by the parameter (this.props)
  • Does not use Redux’s API

Because there is no state, UI components are also referred to as “pure components”, that is, like pure functions, their values are determined purely by parameters. Characteristics of container components (components generated by calling connect()) :

  • Responsible for managing data and business logic, not UI rendering
  • With internal state
  • Use Redux’s API

If a component has both UI and business logic, split it into two parts: a container component on the outside and a UI component on the inside. The former is responsible for communicating with the outside world, passing data to the latter, who is responsible for rendering the view.

pages

pages/todoList/Home.jsx

// pages/todoList/Home.jsx

import React, { Component } from 'react';
import List from '.. /.. /components/List'
import action from './toDoListAction'
import { connect } from 'react-redux'

class Home extends Component {
    state = {
        userInfo: {
            username: ' '.position:' ',
        }
    }
    getUserInfo = (e) = > {
        let userInfo = Object.assign(this.state.userInfo, {[e.target.id]: e.target.value})
        this.setState({
            userInfo
        })
    }
   
    submit = () = > {
        this.props.addItem(this.state.userInfo)
        this.setState({
            userInfo: {
                username: ' '.position:' ',}})}render() {
        return (
            <div>
                username: <input type="text" id="username" value={this.state.userInfo.username} onChange={this.getUserInfo}/> 
                position: <input type="text" id="position" value={this.state.userInfo.position} onChange={this.getUserInfo}/>
                <button onClick={this.submit}>submit</button>
                <List></List>
            </div>)}}// Without receiving the state, expand the action object to get the methods defined in the action
export default connect(null, {... action})(Home)Copy the code

The Home is the UI component, and the container component is generated through connect()(Home).

Pages/todoList/toDoListAction. Js – define the action file


const ADD_TODO_ITEM = "ADD_TODO_ITEM"
const UPDATE_CHECKED = 'UPDATE_CHECKED'
const DELETE_USER = 'DELETE_USER'
const action = {
    addItem : (userInfo) = > {
        const sendAction =  {
            type: ADD_TODO_ITEM,
            userInfo
        }
        return sendAction
    },
    updatedChecked: (id) = > {
        const action = {
            type: UPDATE_CHECKED,
            id
        }
        return action
    },
    deleteUser: (id) = > {
        const action = {
            type: DELETE_USER,
            id
        }
        return action
    }
}

export default action
Copy the code

Pages/todoList/toDoListReducer. Js – reducer function used to deal with the current component


const toDoList = [
    {id: 1.username: 'Zhu Yuanzhang'.position: 'Ming Tai Zu'.isChecked: true},
    {id: 2.username: 'Chu Yunwen'.position: 'Emperor Jianwen'.isChecked: false},]const reducer = (state = toDoList, action) = > {

    switch (action.type) {
        case 'ADD_TODO_ITEM':
            return handler.addItem(state,action.userInfo)
        case 'UPDATE_CHECKED':
            return handler.updateChecked(state, action.id)
        case 'DELETE_USER':
            return handler.deleteUser(state, action.id)

        default:
            return state
    }
}

const handler = {
    addItem: (arr,userInfo) = > {
        const newArr = JSON.parse(JSON.stringify(arr))
        // React-redux internally determines whether a component is rerendered by determining whether the address of the state received in the component (the state value in the connect(mapStateToprops) function) has changed.
        // Prevents components from being re-rendered while manipulating the contents of the array without changing the address of the array. Therefore, make a new copy of the array to distinguish it from the original one.
        userInfo = Object.assign(userInfo, {id: arr.length + 1})
        newArr.push(userInfo)
        return newArr
    },
    updateChecked: (arr, id) = > {
        const newArr = arr.slice()
        for(let i=0; i<newArr.length; i++){if(newArr[i].id === id){ newArr[i].isChecked = ! newArr[i].isChecked } }return newArr
    },
    deleteUser: (arr, id) = > {
        return arr.filter(item= > {
            return item.id === id ? false : true}}})export default reducer
Copy the code

Components – the child component

components/List.jsx

import React, { Component, useState } from 'react';
import action from '.. /pages/todoList/toDoListAction'
import { connect } from 'react-redux'


const Item = (props) = > {
    const [liStyle] = useState({
        color: 'springgreen',})// Change the status of the check box
    const updatedChecked = () = > props.updatedChecked(props.item.id)
    // Delete the current user
    const deleteUser = () = > props.deleteUser(props.item.id)
    
    return <li style={props.item.isChecked ? liStyle : {}}  id={props.item.id}>
              <input type="checkbox" checked={props.item.isChecked || ''} onChange={updatedChecked}/>
              {props.item.username} ---- {props.item.position} 
              <button onClick={deleteUser}>Delete user</button>
           </li>
}

 class List extends Component {

    render() {
        console.log(this.props);
        return (
            <div>
                <ul>
                    {
                        
                        this.props.todoList.map((item) => {
                        return <Item item={item} key={item.id} {. this.props} / >})}</ul>
            </div>)}}/* const mapStateToProps = (state) => { return { todoList: state.toDoListReducer } } const mapDispatchToProps = (dispatch) => { return { updatedChecked: (id) => { dispatch(action.updatedChecked(id)) }, deleteUser: (id) => dispatch(action.deleteUser(id)) } } export default connect(mapStateToProps, mapDispatchToProps)(List) */

// The above code can be abbreviated as:
export default connect(state= > ({ todoList: state.toDoListReducer }), { ... action })(List)Copy the code

Export default connect(mapStateToProps, mapDispatchToProps)(List) accepts two parameters:

MapStateToProps and mapDispatchToProps.

The former is responsible for the input logic, which maps state to the parameters (props) of the UI component. MapStateToProps is a function that takes a state as an argument and returns an object. Each of these key-value pairs is a mapping. MapStateToProps subscribes to the Store, and every time state is updated, it automatically recalculates the PARAMETERS of the UI component, triggering a re-rendering of the UI component.

The latter is responsible for the output logic, which maps user actions to UI components as actions. Used to map UI component parameters to the store.dispatch method. That is, it defines which user actions should be passed to the store as actions. It can be either a function or an object.

Reducer – Merge the private reducer

reducer/index.js

import {combineReducers} from 'redux'
import toDoListReducer from '.. /pages/todoList/toDoListReducer'

Merge the private Reducer defined by each component by calling the combineReducers method
export default combineReducers({
    toDoListReducer
})
Copy the code

Store — Create a store repository

store/index.js

import { createStore } from 'redux'
import reducer from '.. /reducer'

const store = createStore(reducer)
 
export default store
Copy the code

App component

import React from 'react'
import { Provider } from 'react-redux'
import store from './05-communication-react-redux/store'

import Home from './05-communication-react-redux/pages/todoList/Home'

function App() {
  return (
    <Provider store={store}>
      <div className="App">
        <Home></Home>
      </div>
    </Provider>
 
  );
}

export default App;
Copy the code

Use Provider to cover the root component so that all child components of the App get state by default. It works like this: The React component context property.

Function component state management — React-redux

Use useSelector and useDispatch provided by React-Redux in function components for state management.

pages

// pages/todoList/Home.jsx
import React, { useState, useEffect } from 'react';
import List from '.. /.. /components/List'
import action from './toDoListAction'
import { useDispatch } from 'react-redux'
export default() = > {let [userInfo, setUserInfo] = useState({
        username: ' '.position:' '});const dispatch = useDispatch()
    const getUserInfo = (e) = > {
        let currentUserInfo = Object.assign(userInfo, {[e.target.id]: e.target.value})
        const current = JSON.parse(JSON.stringify(currentUserInfo))
        // currentUserInfo is changed on the original object, the address of userInfo has not changed, so it will not trigger component update, so you can copy current and assign it to userInfo to trigger component update.
        setUserInfo(current)
    }
   
    const submit = () = > {
        dispatch(action.addItem(userInfo))
        setUserInfo({
            username: ' '.position:' '})},return (
        <div>
            username: <input type="text" id="username" value={userInfo.username} onChange={getUserInfo}/> 
            position: <input type="text" id="position" value={userInfo.position} onChange={getUserInfo}/>
            <button onClick={submit}>submit</button>
            <List></List>
        </div>)}Copy the code
// pages/todoList/toDoListAction.js

const ADD_TODO_ITEM = "ADD_TODO_ITEM"
const UPDATE_CHECKED = 'UPDATE_CHECKED'
const DELETE_USER = 'DELETE_USER'
const action = {
    addItem : (userInfo) = > {
        const sendAction =  {
            type: ADD_TODO_ITEM,
            userInfo
        }
        return sendAction
    },
    updatedChecked: (id) = > {
        const action = {
            type: UPDATE_CHECKED,
            id
        }
        return action
    },
    deleteUser: (id) = > {
        const action = {
            type: DELETE_USER,
            id
        }
        return action
    }
}

export default action
Copy the code
// pages/toDoListReducer.js

const toDoList = [
    {id: 1.username: 'Zhu Yuanzhang'.position: 'Ming Tai Zu'.isChecked: true},
    {id: 2.username: 'Chu Yunwen'.position: 'Emperor Jianwen'.isChecked: false},]const reducer = (state = toDoList, action) = > {
    switch (action.type) {
        case 'ADD_TODO_ITEM':
            return handler.addItem(state,action.userInfo)
        case 'UPDATE_CHECKED':
            // console.log(handler.updateChecked(newState, action.id))
            return handler.updateChecked(state, action.id)
        case 'DELETE_USER':
            return handler.deleteUser(state, action.id)

        default:
            return state
    }
}

const handler = {
    addItem: (arr,userInfo) = > {
    	// Use the arR array directly. Don't know why not in the class component
        const newArr = JSON.parse(JSON.stringify(arr))
        userInfo = Object.assign(userInfo, {id: arr.length + 1})
        newArr.push(userInfo)
        return newArr
    },
    updateChecked: (arr, id) = > {
        const newArr = arr.slice()
        for(let i=0; i<newArr.length; i++){if(newArr[i].id === id){ newArr[i].isChecked = ! newArr[i].isChecked } }return newArr
    },
    deleteUser: (arr, id) = > {
        return arr.filter(item= > {
            return item.id === id ? false : true}}})export default reducer
Copy the code

components

// components/List.jsx
import React, { useState } from 'react';
import action from '.. /pages/todoList/toDoListAction'
import { useSelector, useDispatch } from 'react-redux'


const Item = (props) = > {
    const [liStyle] = useState({
        color: 'springgreen',})const dispatch = useDispatch()

    const updatedChecked = () = > dispatch(action.updatedChecked(props.item.id))
    
    const deleteUser = () = > dispatch(action.deleteUser(props.item.id))
    
    return <li style={props.item.isChecked ? liStyle : {}}  id={props.item.id}><input type="checkbox" checked={props.item.isChecked || ''} onChange={updatedChecked}/> {props.item.username} ---- {props.item.position} <button onClick={deleteUser}>Delete user</button></li>
}


export default() = > {const todoList = useSelector(state= > state.toDoListReducer)
    return (
        <div>
            <ul>
                {
                    
                    todoList.map((item) => {
                    return <Item item={item} key={item.id} />})}</ul>
        </div>)}Copy the code

Reducer reducer – merger

// reducer/index.js

import {combineReducers} from 'redux'
import toDoListReducer from '.. /pages/todoList/toDoListReducer'
import calculatorReducer from '.. /pages/calculator/calculatorReducer'


export default combineReducers({
    toDoListReducer,
    calculatorReducer
})
Copy the code

Store – to create a store

// store/index.js
import { createStore } from 'redux'
import reducer from '.. /reducer'

const store = createStore(reducer)
 
export default store
Copy the code

App.js

import React from 'react'
import { Provider } from 'react-redux'
import store from './05-communication-react-redux/store'

import Home from './06-communication-react-redux-hooks/pages/todoList/Home'

function App() {
  return (
    <Provider store={store}>
      <div className="App">
        <Home></Home>
      </div>
    </Provider>
 
  );
}

export default App;

Copy the code