• 三、【react-redux】数据共享


    本示例修改自 上一章 求和Demo

    1、优化项目结构

    • 将redux下的action和reducer单独分类方便管理,因为现在要写第二个第三个第n个容器组件了

    在这里插入图片描述

    2、添加一个新容器组件

    2.1、新项目结构

    在这里插入图片描述

    2.2、CODE

    2.2.1、reduc/constant.js

    /**
     * action.type常量
     */
    // for Count
    export const INCREMENT = 'increment'
    export const DECREMENT = 'decrement'
    // for Person
    export const ADD_PERSON = 'add_person'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2.2.2、redux/actions/person.js

    import { ADD_PERSON } from '../constant'
    
    // 创建添加一个人信息的动作对象
    export const createAddPersonAction = data => ({ type: ADD_PERSON, data })
    
    • 1
    • 2
    • 3
    • 4

    2.2.3、redux/reducers/person.js

    import { ADD_PERSON } from '../constant'
    
    export default function personReducer(preState = [], action) {
        const { type, data } = action
        switch (type) {
            case ADD_PERSON:
                return [data, ...preState]
            default:
                return preState
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2.2.4、redux/store.js

    import {
        // 引入createStore,专门用于创建redux中最为核心的store对象
        createStore,
        // 引入applyMiddleware 执行中间件
        applyMiddleware,
        // 引入 combineReducers 组合 reducers
        combineReducers
    } from 'redux'
    //引入reducers
    import countReducer from './reducers/count'
    import personReducer from './reducers/person'
    // 引入 redux-thunk 用于支持异步action
    import thunk from 'redux-thunk'
    
    // 共享就得把 reducer 组合到一起传进去
    const allReducers = combineReducers({
        count: countReducer,
        people: personReducer
    })
    
    //暴露store
    export default createStore(allReducers, applyMiddleware(thunk))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    2.2.5、Count.jsx

    // import 未改变,略...
    
    class Count extends Component {
        // 方法等都未改变,略...
    
        render() {
            const { count, people } = this.props
            return (
                <div>
                    <h2>我是Count,下面已经添加了{people.length}个人</h2>
                    {/* 内容全部未变,略... */}
                </div >
            )
        }
    }
    
    // 暴露容器组件
    export default connect(
        state => ({
            count: state.count,
            people: state.people
        }),
        {
            // 未改变,略...
        }
    )(Count)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    2.2.6、Person.jsx

    import React, { Component } from 'react'
    import { connect } from 'react-redux'
    import { nanoid } from 'nanoid'
    import { createAddPersonAction } from '../../redux/actions/person'
    
    class Person extends Component {
        state = {
            name: '',
            age: '',
        }
    
        submit = () => {
            this.props.add({
                id: nanoid(),
                ...this.state
            })
    
            // 清空表单
            this.setState({
                name: '',
                age: ''
            })
        }
        render() {
            const { name, age } = this.state
            const { people, count } = this.props
            return (
                <div>
                    <h2>我是Person,上面求和为{count}</h2>
                    <input
                        type='text'
                        name="name"
                        placeholder='请输入名字'
                        value={name}
                        onChange={e => this.setState({ name: e.target.value })}
                    /><br />
                    <input
                        type='text'
                        name="age"
                        placeholder='请输入年龄'
                        value={age}
                        onChange={e => this.setState({ age: e.target.value })}
                    /><br />
                    <button onClick={this.submit}>添加</button><br />
                    <ul>
                        {
                            people.map(i => (
                                <li key={i.id}>
                                    {`姓名:${i.name}-年龄:${i.age}`}
                                </li>
                            ))
                        }
                    </ul>
                </div >
            )
        }
    }
    
    export default connect(
        state => ({
            people: state.people,
            count: state.count
        }),
        {
            add: createAddPersonAction
        }
    )(Person)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67

    2.3、Result

    在这里插入图片描述

    3、总结

    1. 定义一个Pserson组件,和Count组件通过redux共享数据
    2. 为Person组件编写:reducer、action,配置constant常量
    3. 重点:Person的reducer和Count的Reducer要使用combineReducers进行合并,合并后的总状态是一个对象!!!
    4. 交给store的是总reducer,最后注意在组件中取出状态的时候,记得“取到位”

    *补充:纯函数

    1. 一类特别的函数: 只要是同样的输入(实参),必定得到同样的输出(返回)
    2. 必须遵守以下一些约束
    3. 不得改写参数数据
    4. 不会产生任何副作用,例如网络请求,输入和输出设备
    5. 不能调用Date.now()或者Math.random()等不纯的方法

    redux的reducer函数必须是一个纯函数

  • 相关阅读:
    选择题示例
    IntelliJ IDEA 2024 中文激活版 mac/win
    Mybatis日期检索格式报错
    CSS画圆以及CSS实现动态圆
    Git分支管理(IDEA)
    promise
    【无标题】
    DC-DC选型及电路设计
    ES6面向对象思想和构造对象方式
    HTML5期末作业:明星网站设计与实现——明星薛之谦介绍网页设计7个页面HTML+CSS+JavaScript
  • 原文地址:https://blog.csdn.net/qq_30769437/article/details/128128211