react - component communication

        Component communication is divided into communication between parent-child components and non-parent-child communication. In parent-child component communication, parent-to-son (transfer data) and word-to-father (transfer method) are used in parent-child component communication. Class components have more this, Function components do not need this. Non-parent-child component communication, cross-domain is relatively large, and there are many nested component levels, so it will be relatively complicated, but there are also ways to achieve it: state promotion (middleman mode, the premise is that it must be a brother, and it is not applicable after the relationship is complicated. ), publish subscriber mode (redux is used in actual development), context state tree parameter passing (official method)

1. Father-son communication

(1) class components

The following code mid-level demonstrates parent-to-child transmission (passing values ​​to child components through attribute name={passed value}, and accepting values ​​from parent components through this.props.property name in child components)

It also demonstrates the child-to-parent (the child component submits a function to the parent component through its own method, triggering the method of the parent component)

import React, { Component } from 'react'


// 父传子在上一个案例中讲过了,通过props属性传值

// 父组件
export default class App7 extends Component {
    state = {
        num: 1
    }
    // 父组件中的方法执行的事情
    addFnFat=()=>{
        this.setState({
            num:this.state.num+1
        })
    }
    render() {
        return (
            <div>
                {/* 通过 */}
                <div>子组件中触发的加一:{this.state.num}</div>
                {/* 通过属性名={传递的值} 来向子组件传值   通过方法名={方法} 来向子组件传递一个方法*/}
                <Sub1 num={this.state.num} addFnFat={this.addFnFat}/>
            </div>
        )
    }
}

// 子组件
class Sub1 extends Component {
    // 子组件通过自身的方法,像父组件提交了一个功能,触发父组件的方法
    addfn = () => {
        // 触发父组件的传来的方法
        this.props.addFnFat()

    }
    render() {
        return (
            <div>
                <div>
                    {/* 通过this.props.属性名 来接受父组件传来的值 */}
                    父组件传来的数值:{this.props.num}
                </div>
                <button onClick={this.addfn}>加一</button>
            </div>
        )
    }
}

(2) Function components

The following code mid-level demonstrates parent-child transmission (passing values ​​to child components through attribute name = {passed value}, and child components accept values ​​from parent components through props. attribute name)

It also demonstrates the child-to-parent (the child component submits a function to the parent component through its own method, triggering the method of the parent component)

import React,{useState} from 'react'

export default function App9() {
    const [num,setNum] = useState(1)//定义一个变量num
    const addFnFat=()=>{
        setNum(num+1)//修改num,使之加一
    }
    return (
        <div>
            <div>子传父更改的值:{num}</div>
             {/* 通过属性名={传递的值} 来向子组件传值   通过方法名={方法} 来向子组件传递一个方法*/}
            <Sub num={num} addFnFat={addFnFat}/>
        </div>
    )
}

function Sub(props) {
    const addfn = () => {
        // 触发父组件的传来的方法
        props.addFnFat()

    }
    return (
        <div>
            <div>
                {/* 通过props.属性名 来接受父组件传来的值 */}
                父组件传来的数值:{props.num}
            </div>
            <button onClick={addfn}>加一</button>
        </div>
    )
}

The difference between parent-child communication between class components and function components above is that class components have an extra this, while function components do not need this. The difference between subsequent class components and function components is this, so I won’t go into details.

2. Non-father-son communication

(1) Status improvement (middleman)

1. Realize ideas     

A middleman appears, the role of this middleman is equivalent to a father, in charge of the two sons, the communication between the two sons needs to be transmitted through the father

 2. Code implementation: son 2 wants to accept the data in son 1 and add 1

import React, { Component } from 'react'
/* 
儿子2 想接受儿子1里面的数据,并实现加1,
*/

// 中间人
export default class App11 extends Component {
    state={
        acceptNum:0//用来接受儿子1传来的值
    }

    tranNum = (sub1Value) => {
        console.log("能接受到儿子1传来的值吗?",sub1Value);
        // 将儿子1传来的值放到父亲身上
        this.setState({
            acceptNum:sub1Value
        })
    }
    tranNum2 = (sub2Value) => {
        console.log("能接受到儿子2传来的值吗?",sub2Value);
        // 将儿子1传来的值放到父亲身上
        this.setState({
            acceptNum:sub2Value
        })
    }
    render() {
        return (
            <div>

                <Sub1 tranNum={this.tranNum} />
                <div>{this.state.acceptNum}</div>
                <hr />
                {/* 将儿子1传来的值,通过父亲转接,传给儿子2 */}
                <Sub2 sub1Num={this.state.acceptNum} tranNum2={this.tranNum2}/>
                <hr />
                {/* 儿子2更改后的的值传回给儿子1 */}
                <Sub1 sub2Num={this.state.acceptNum} />

            </div>
        )
    }
}
// 儿子1
class Sub1 extends Component {
    state = {
        num: 1
    }
    // 儿子1向父亲传递num里面的值
    transferFn = (num) => {
        this.props.tranNum(num)
    }
    render() {
        return (
            <div>
                <button onClick={this.transferFn.bind(this, this.state.num)}>Sub1向父亲传值</button>
                <div>拿到儿子2通过加一后传来的值{this.props.sub2Num}</div>
            </div>
        )
    }
}

// 儿子2
class Sub2 extends Component {
    // 儿子2修改了儿子1的值,并给父亲发了个指令
    addFn=(sub1Num)=>{
        var sub2Num = sub1Num+1
        this.props.tranNum2(sub2Num)
    }
    render() {
        return (
            <div>
                <div>儿子2经过父亲,拿到儿子1传来的值:{this.props.sub1Num}</div>
                <button onClick={this.addFn.bind(this,this.props.sub1Num)}>加一</button>
            </div>
        )
    }
}

 Disadvantages : It can only be implemented on siblings, and it is not applicable after the relationship is complicated, because the transmitted relationship is too complicated, which is not conducive to developer development, and other methods can be chosen to achieve this, such as cross-component publish-subscriber mode and context, etc.

(2) Publish subscriber mode

        The actual development will not use the native publish-subscriber mode, but will use the redux (encapsulated based on publish-subscriber) method to realize this non-parent-child communication mode

1. Implementation idea

        The publisher subsrcibe() saves the function to the list array and waits to run, which can be published multiple times

        The subscriber calls the publish() function to run all the functions in the list array. The subscriber cannot be written in front of the publisher, and can subscribe multiple times, and the subscriber can pass parameters to the publisher to get

2. Realize the code

import React, { Component } from 'react'

export default class App8 extends Component {
    render() {
        return (
            <div>发布订阅</div>
        )
    }
}
var bus = {
    list:[],
    // 发布
    subscribe(callback) {
        console.log(callback);
        this.list.push(callback)

    },
    // 订阅
    publish(text) {//text传的参数
        // 遍历所有的lisy,将回调函数执行
        this.list.forEach(callback=>{
            callback&&callback(text)
        })

    }
}
// 订阅者
bus.subscribe((value)=>{//value接受发布者传来的参数
    console.log('111',value);
})
bus.subscribe(()=>{
    console.log("121");
})
bus.publish("传进去的参数")

(3) Context state tree parameter transfer (official method)

        In the new context API, React provides a createContext method, which returns an object containing Provider and Consumer. It should be noted that the provider must be a certain level of parent of the consumer.

1. Implementation process

context(1) Define the global object first

(2) The root component is introduced GlobalContextand used GlobalContext.Provider(producer)

(3) In the class component, any component is introduced GlobalContextand called Context, used GlobalContext.Consumer(consumer), returns a function, and passes in value.

value. variable get data

value. method get method

{
    // 必须要是一个箭头函数
    (value) => {
        return (//必须要return出去
          <div>
              <div>生产者提供的值:{value.num}</div>
              <button onClick={this.addFn.bind(this, value)}>加一</button>
          </div>
        )
     }
}

(4) In functional components, parameters are obtained by using the useContext provided by hooks.

value. variable get data

value. method get method

    const value = useContext(GlobalContext)
    console.log(value);
    const addFn = (value) => {
        value.changeNum()
    }
    return (
        <div>
            <div>生产者提供的值:{value.num}</div>
            <button onClick={() => addFn(value)}>加一</button>
        </div>
    )

2. Realize the code

(1) Class components:

import React, { Component, createContext } from 'react'
/* 
1、实现过程
(1)先定义全局context对象

(2)根组件引入GlobalContext,并使用GlobalContext.Provider(生产者)

(3)任意组件引入GlobalContext并调用Context,使用GlobalContext.Consumer(消费者)
*/
// 1、全局定义context对象
const GlobalContext = React.createContext()

// 生产者
export default class Context extends Component {
    state = {
        num: 1
    }
    render() {
        return (
            // 一定要为父标签,作为唯一的根标签
            <GlobalContext.Provider value={
   
   {
                num: this.state.num,//传递过去的值
                changeNum: (value) => {
                    this.setState({
                        num: this.state.num + 1
                    })
                }
            }}>

                <Consumer />

            </GlobalContext.Provider>
        )
    }
}

// 消费者
class Consumer extends Component {
    // 消费者向生产者发送的指令
    addFn = (value) => {
        // 执行生产者中的方法
        value.changeNum()
    }
    render() {
        return (
            <GlobalContext.Consumer>
                {
                    // 必须要是一个箭头函数
                    (value) => {
                        return (//必须要return出去
                            <div>
                                <div>生产者提供的值:{value.num}</div>
                                <button onClick={this.addFn.bind(this, value)}>加一</button>
                            </div>
                        )
                    }
                }
            </GlobalContext.Consumer>
        )
    }
}

(2) Functional components - useContext()

There is no way to introduce useContext

import React,{useState} from 'react'
// 1、全局定义context对象
const GlobalContext = React.createContext()
export default function App() {
    const [num,setNum] = useState(0)
    return (
        // 一定要为父标签,作为唯一的根标签
        <GlobalContext.Provider value={
   
   {
            num: num,//传递过去的值
            changeNum: (value) => {
                setNum(num + 1)
            }
        }}>

            <Sub1 />

        </GlobalContext.Provider>
    )
}
function Sub1(){
    const addFn=(value)=>{
        value.changeNum()
    }
    return (
        <GlobalContext.Consumer>
            {
                // 必须要是一个箭头函数
                (value) => {
                    console.log(value);
                    return (//必须要return出去
                        <div>
                            <div>生产者提供的值:{value.num}</div>
                            <button onClick={()=>addFn(value)}>加一</button>
                        </div>
                    )
                }
            }
        </GlobalContext.Consumer>
    )
}

Introduce the wording of useContext

import React, { useState, useContext } from 'react'
// 1、全局定义context对象
const GlobalContext = React.createContext()
export default function App() {
    const [num, setNum] = useState(0)
    return (
        // 一定要为父标签,作为唯一的根标签
        <GlobalContext.Provider value={
   
   {
            num: num,//传递过去的值
            changeNum: (value) => {
                setNum(num + 1)
            }
        }}>

            <Sub1 />

        </GlobalContext.Provider>
    )
}
function Sub1() {
    const value = useContext(GlobalContext)
    console.log(value);
    const addFn = (value) => {
        value.changeNum()
    }
    return (
        <div>
            <div>生产者提供的值:{value.num}</div>
            <button onClick={() => addFn(value)}>加一</button>
        </div>
    )
}

3. Pay attention 

(1) The provider must be a certain level of parent of the consumer

(2) The structure of the consumer must be an arrow function, and must return out

(3) The same is true for the implementation of function components, except that the stored variables need to use useState

(4) Flux

        Flux is a kind of architecture idea, which is used to build the application architecture of client applications, and specifically solves the structural problems of software. It is used in conjunction with react. It is the same type of thing as mvc architecture. It uses one-way data flow combined with react in View software, but it is simpler, clearer, and easy to use. In actual development, this is less used, and redux is used more.

 1. User access view

 2. The view sends the user's action

 3. The dispatcher receives the action and requires the store to update accordingly

 4. After the store is updated, a change event is issued

 5. After the view receives the change event, it updates the page

(5) Redux

1. Concept

        It is given on the official website: Redux is a pattern and tool library that uses events called "action" to manage and update the application state. It uses a centralized Store (centralized store) to centrally manage the state used in the entire application. Its rules Make sure state is only updated in predictable ways. Redux Basics Tutorial, Section 1: Redux Overview and Concepts | Redux Chinese Official Website

        The explanation on the official website is very official, but it is very difficult for learners to understand, and we only need to remember the official concept, and then know the application scenario + how to use it.

2. Application scenarios

        Redux is a useful framework, but it doesn't have to be used. Someone once said: "If you don't know if you need redux, you don't need it". Dan Abramov, the creator of Redux, also said: "You only need redux if you encounter problems that react can't solve", so when should you use it?

From a project perspective :

        The way users use it is complex

        Users with different identities have different usage methods (ordinary users and administrators)

        Collaboration between multiple users

        Interact heavily with the server, or use WebSocket

        View needs to get data from multiple sources

From a component perspective :

        The state of a component needs to be shared

        A state needs to be available anywhere

        A component needs to change the global state

        A component needs to change the state of another component

3. Design thinking

        Use a centralized global state to manage the application, and explicitly update the state mode to make the code predictable. All states are stored in an object, and the final idea is still the publish-subscriber mode, which has three principles:

        unique source of data

        keep read-only

        Data changes can only be performed by pure functions

4. Redux Terminology

(1)Action

Describes what event happened in the application, has two parameters

        type : String, give the action a descriptive name, the usual format is "domain/event name", domain: is the feature or category to which the action belongs; event name: what happened specifically

        action : can have other fields with additional information about what happened, usually put this information in a field called payload

// 创建action对象 
const action = { 
    type: "changeInputValue", // type属性是必须要写的,用于校验 
    value: e.target.value, // value代表要修改为什么值
 }

(2)reducer

        It is a function that receives the current state (initial value) and an action object. It is necessary to decide how to update the state and return the new state. Can be regarded as an event listener, processing events according to the type of action received

                state: refers to the state in the original warehouse

                action: refers to the state of the new delivery of the action

        The logic inside the function usually follows the steps: Check whether the reducer cares about the action, if so, assign the state, update the state copy with the new value, and then return the new state; otherwise return the original state unchanged

//初始默认值 
const initialState = { 
    value: 0 
} 
//state:指的是原始仓库里的状态 
//action:指的是action新传递的状态 
function counterReducer(state = initialState, action) { 
    // 检查 reducer 是否关心这个 
    action if (action.type === 'counter/increment') { 
        // 如果是,复制 `state` 
        return { 
            ...state, // 使用新值更新 state 副本 
            value: state.value + 1 
        } 
    } 
    // 返回原来的 state 不变 
    return state 
}

Usually use switch to traverse

(3)store

        Equivalent to a warehouse, the state of the current redux application exists in an object named store

        Created by passing in the reducer

        Get the contents of the warehouse through getState() and return the current state value

// 引入createStore对象 
import { createStore } from 'redux' // 引入reducer 
import reducer from './reducer' 

const store = createStore( reducer ); 
export default store; //获取当前状态值 
// 引入store 
import store from './store' var xxx = store.getState()

(4)dispatch

        The only way to update the state is to call store.dispatch() and pass in an action object. The store will execute all reducer functions and calculate the updated state. Call getState() to get the new state.

store.dispatch({ type: 'counter/increment' }) 
console.log(store.getState()) // {value: 1}

5. Install the Redux DevTools extension

Purpose: Debug redux state values ​​in the browser. The installation address of the browser corresponding to the extension is given on the official website. The one that applies to me here is the Chrome version. Of course, you can also search and download it by yourself. You don’t need to decompress it, just drag it into the browser extension, and then configure window.__REDUX_DEVTOOLS_EXTENSION__ && in the program window.__REDUX_DEVTOOLS_EXTENSION__(), after restarting the browser, it can be used

// 引入createStore对象 
import { createStore } from 'redux' 
// 引入reducer 
import reducer from './reducer' 

const store = createStore( 
    reducer, 
    window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
); 
export default store;

6. Use case - counter

(1) Create project installation

// 创建项目

    npx create-react-app 项目名

// 安装

    redux yarn add redux

(2) Configure redux structure

Create index and reducer after creating redux under src

index.js

// 引入createStore对象 
import { createStore } from 'redux' 
// 引入reducer 
import reducer from './reducer' 

const store = createStore( 
    reducer, 
    window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
); 
export default store;

reducer.js

//初始值 
const initState={ 
    num:0//用于计数的变量 
} 
// 导出一个函数,用于返回state 
export default (state = initState, action) => { 
    return state; 
}

(3) Page structure

(3)-1. Function component form

import React, { useState, useEffect } from 'react' 
import store from '../redux' 

export default function Count() { 
    const [state, setState] = useState(0) 
    // var state = store.getState() 
    // console.log("1",state.num); 
    console.log("store", store); 
    useEffect(() => { store.subscribe(() => { 
        setState(store.getState().num) }) 
    }, [state]) console.log("1", state); 
    return ( 
        <div> 计数器 
        <AddFn /> 
        <div>{state}</div> 
        <JianFn /> 
        </div> 
    ) 
} 

// 子组件1做加法 
function AddFn() { 
    const add = () => { 
        console.log("jia"); 
        const addAction = { type: "add" } 
        store.dispatch(addAction) 
    } 
    return ( 
        <div onClick={add}>加1</div> 
    ) 
} 

// 子组件2做减法 
function JianFn() { 
    const jian = () => { 
        console.log("jian"); 
        const jianAction = { type: "jian" } 
        store.dispatch(jianAction) 
    } 
    return ( 
        <div onClick={jian}>减1</div> 
    ) 
}

(3)-2, class component form

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

export default class Count1 extends Component {

        state = { num:0 }

        constructor(p){

                super(p)

                this.state={ num:0 }

                this.state = store.getState()

                store.subscribe(this.storeChange.bind(this))

                // console.log("11",this.state);

        }

        storeChange(){

                this.setState( store.getState() )

        }

        render() {

                return (

                <div>

                        <Add/>

                        {this.state.num}

                        <Jian/>

                </div>

        )

     }

}



// 子组件1加

class Add extends Component {

        add=()=>{

                console.log("jia ");

                store.dispatch({type:"add"})

        }

        render() {

                return (

                        <div onClick={this.add.bind(this)}>加1</div>

                )

        }

}

// 子组件2减

class Jian extends Component {

        jian=()=>{

                console.log("jian"); store.dispatch({type:"jian"})

        }

        render() {

                return (

                        <div onClick={this.jian.bind(this)}>减1</div>

                )

        }

}

7、ActionTypes

        In actual development, many actions will be written, and many types will appear in them. In order to facilitate management and improve reusability, you can extract the type in the action for unified management, and create a new actionTypes.js file under the redux folder

export const ADD = "add"; 
export const JIAN = "jian";
export const DEL_LIST_ITEM = "delListItem";

Import actionTypes in reducer.js and replace type

import { ADD, JIAN, DEL_LIST_ITEM } from './actionTypes' 
const initState={ num:0 } 
// 导出一个函数,用于返回state 
export default (state = initState, action) => { 
    let newState = JSON.parse(JSON.stringify(state)); // 对原本的state做一次深拷贝                 
    console.log(action); 
    switch(action.type){ 
        case ADD: 
            newState.num +=1; 
            console.log(newState); 
            return newState; 
        case JIAN: 
            newState.num -=1; 
            return newState; 
        default: 
            break; 
    } 
    return newState;
}

The page also imports actionTypes and replaces type with

//类组件 
import React, { Component } from 'react' 
import store from '../redux'; 
import { ADD, JIAN, DEL_LIST_ITEM } from '../redux/actionTypes' 

export default class Count1 extends Component { 
    state = { num:0 } 
    constructor(p){ 
        super(p) 
        this.state={ num:0 } 
        this.state = store.getState() 
        store.subscribe(this.storeChange.bind(this)) 
        // console.log("11",this.state); } 
        storeChange(){ 
            this.setState( store.getState() ) 
        } 
        render() { 
            return ( 
                <div> <Add/> {this.state.num} <Jian/> </div> 
            ) 
        } 
} 

// 子组件1加 
class Add extends Component { 
    add=()=>{ 
        console.log("jia "); 
        store.dispatch({type:ADD}) 
    } 
    render() { 
        return ( 
            <div onClick={this.add.bind(this)}>加1</div> 
        ) 
    } 
} 

// 子组件2减 
class Jian extends Component { 
    jian=()=>{ 
        console.log("jian"); 
        store.dispatch({type:JIAN}) 
    } 
    render() { 
        return ( 
            <div onClick={this.jian.bind(this)}>减1</div> 
        ) 
    } 
}
//函数组件 
import React, { useState, useEffect } from 'react' 
import store from '../redux' 
import { ADD, JIAN, DEL_LIST_ITEM } from '../redux/actionTypes'
 
export default function Count() { 
    const [state, setState] = useState(0) 
    // var state = store.getState() 
    // console.log("1",state.num); 
    console.log("store", store); 
    useEffect(() => { 
        store.subscribe(() => { 
        setState(store.getState().num) }) 
    }, [state]) 
    console.log("1", state); 
    return ( 
        <div> 计数器 <AddFn /> <div>{state}</div> <JianFn /> </div> 
    ) 
} 

// 子组件1做加法 
function AddFn() { 
    const add = () => { 
        console.log("jia"); 
        const addAction = { type: ADD } 
        store.dispatch(addAction) 
    } 
    return ( 
        <div onClick={add}>加1</div> 
    ) 
} 


// 子组件2做减法 
function JianFn() { 
    const jian = () => { 
        console.log("jian"); 
        const jianAction = { type: JIAN } 
        store.dispatch(jianAction)
     } 
    return ( 
        <div onClick={jian}>减1</div> 
    ) 
}

8、ActionCreator

In actual development, actions will also be managed in one file actionCreator.js

import { ADD, JIAN, DEL_LIST_ITEM } from './actionTypes' 

// 计数器的加法 
export const addFnAction = () =>{ 
    return { type:ADD } 
} 

// 计数器的减法 
export const jianFnAction = () =>{ 
    return { type:JIAN } 
}

Delete the previous actionTypes import on the page, import actionCreator, and modify the action

//类组件
import React, { Component } from 'react'
import store from '../redux';
import { addFnAction, jianFnAction} from '../redux/actionCreator'

export default class Count1 extends Component {
    state = {
        num:0
    }
constructor(p){
    super(p)
    this.state={
        num:0
    }
    this.state = store.getState()

    store.subscribe(this.storeChange.bind(this))
    // console.log("11",this.state);
}
storeChange(){
    this.setState(
        store.getState()
     )
}
    render() {
        return (
            <div>
                <Add/>
                {this.state.num}
                <Jian/>
            </div>
        )
    }
}

// 子组件1加
class Add extends Component {
    add=()=>{
        console.log("jia ");
        store.dispatch(addFnAction())
    }
    render() {
        return (
            <div onClick={this.add.bind(this)}>加1</div>
        )
    }
}

// 子组件2减
class Jian extends Component {
    jian=()=>{
        console.log("jian");
        store.dispatch(jianFnAction())
    }
    render() {
        return (
            <div onClick={this.jian.bind(this)}>减1</div>
        )
    }
}
//函数组件
import React, { useState, useEffect } from 'react'
import store from '../redux'
import { addFnAction, jianFnAction} from '../redux/actionCreator'

export default function Count() {
  const [state, setState] = useState(0)
  // var state = store.getState()
  // console.log("1",state.num);
  console.log("store", store);
  useEffect(() => {
    store.subscribe(() => {
      setState(store.getState().num)
    })

  }, [state])
  console.log("1", state);
  return (
    <div>
      计数器
      <AddFn />
      <div>{state}</div>
      <JianFn />
    </div>
  )
}


// 子组件1做加法
function AddFn() {
  const add = () => {
    console.log("jia");
    
    store.dispatch(addFnAction())
  }

  return (
    <div onClick={add}>加1</div>
  )
}


// 子组件2做减法
function JianFn() {
  const jian = () => {
    console.log("jian");
    store.dispatch(jianFnAction())
  }
  return (
    <div onClick={jian}>减1</div>
  )
}

 Finally, we must keep in mind: store must be unique, multiple stores are not allowed, only one store space; only store can change its own content, reducer cannot change; reducer must be a pure function

Six, the difference between Flux and Redux

        1. Flux is just an idea, and Redux is a way to realize the idea

        2. There are multiple stores in Flux to store application data, and the update logic is executed in the stores. When the stores change, the controller-view is notified to update its own data. There is only one store in Redux, and the complete state can be obtained according to this store, and the update logic is no longer in the store, but in the reducer (using pure functions).
        3. Flux has the concept of Dispatcher. Redux does not have the concept of Dispatcher. Reducers are used to process events. There can be multiple reducers. Each reducer is responsible for maintaining a certain part of the overall state tree of the application. Multiple reducers synthesize a root reducer through the combineReducers method to maintain the entire statereducer. A pure function (preState, action) => newState, in a Redux application.

Guess you like

Origin blog.csdn.net/m0_55173487/article/details/128486213