当前位置: 首页 > article >正文

Redux-状态管理组件

一、简介

        react中的状态只属于某个组件。而Redux是一个全局管理js状态的架构,让组件通信更加容易。

之前是状态在所有组件间传递,而redux通过store来实现这个功能。

Redux特性:

1.Single source Of truth,通过store唯一维护状态。

2.可预测性,state + action -> new state

3.纯函数更新store (纯函数 -> 输入决定输出)

举个例子: 待办事项表

function todos(state = [], action){
    switch(action.type){
        case 'ADD_TODO':
            return state.concat([{text: action.text, completed: false}]);
        case 'TOGGLE_TODO':
            return state.map(
                (todo, idx) => {
                    action.index === idx ? {text: todo.text, completed: !toto.completed}
                    : todo
                }
            )
        default:
            return state
        
    }

}

二、核心概览

拿上图举个例子,前端ui产生了deposit和withdraw2个事件,store通过dispatcher分发对应的事件给reducer处理,reducer处理后更新state。前端ui根据state重新渲染。

1.store

Redux的状态机实现,store 通过state存储状态,通过dispatch传播事件,通过Reducer处理事件。

2.action

        action表示变更事件。一般包含event type 和 context。

3.Reducer

        reducer是状态事件处理。

举个例子: 待办事项表

function todoApp(state = initialState, action){
    switch (action.type){
        case ADD_TODO:
            return Object.assign({}, state, {
                todos:[
                    ...state.todos,
                    {
                        text: action.text,
                        completed: false
                    }
                ]
            });
        default:
            return state;
        
    }
}

三、使用示例

用redux实现一个简单计数器,包括增加、减少功能。

import React from 'react';
import {createStore} from 'redux';
function run(){
    // store initial state
    const initialState = { count: 0};
    // reducer
    const counter = (state = initialState, action) => {
        switch (action.type){
            case "PLUS_ONE":
                return {count: state.count + 1};
            case "MiNUS_ONE":
                return {count: state.count - 1};
            case "CUSTOM_COUNT":
                return {
                    count: state.count + action.payload.count
                };
            default:
              return state;
        }  
    }
    // create store
    const store = createStore(counter);
    // Action creator
    function plusOne(){
        return {type: "PLUS_ONE"}
    }
    
    function minusOne(){
        return {type: "MINUS_ONE"};
    }
    function customCount(count){
        return {type: "CUSTOM_COUNT", payload:{count}};
    }
    // 订阅redux 状态变更
    store.subscribe(() => console.log(store.getState()));
    store.dispatch(plusOne());
    store.dispatch(minusOne());
    store.dispatch(customCount(5));
}

export default ()  => {
    <div>
        <button onClick={run}>Run</button>
        <p>* 请打开控制台查看运行结果</p>
    </div>
}

bindActionCreators使用,工具类,可以减少显示dispatch操作

import React from 'react';
import {createStore, bindActionCreators} from 'redux';
function run(){
    // store initial state
    const initialState = { count: 0};
    // reducer
    const counter = (state = initialState, action) => {
        switch (action.type){
            case "PLUS_ONE":
                return {count: state.count + 1};
            case "MiNUS_ONE":
                return {count: state.count - 1};
            case "CUSTOM_COUNT":
                return {
                    count: state.count + action.payload.count
                };
            default:
              return state;
        }  
    }
    // create store
    const store = createStore(counter);
    // Action creator
    function plusOne(){
        return {type: "PLUS_ONE"}
    }
    
    function minusOne(){
        return {type: "MINUS_ONE"};
    }
    function customCount(count){
        return {type: "CUSTOM_COUNT", payload:{count}};
    }

    plusOne = bindActionCreators(plusOne, store.dispatch);
    minusOne = bindActionCreators(minusOne, store.dispatch);
    customCount = bindActionCreators(customCount, store.dispatch);
    // 订阅redux 状态变更
    store.subscribe(() => console.log(store.getState()));
    plusOne();
    minusOne();
    customCount(5);
}

export default ()  => {
    <div>
        <button onClick={run}>Run</button>
        <p>* 请打开控制台查看运行结果</p>
    </div>
}

四、结合React使用

使用Connect功能,将redux的action和state作为props传递给组件。

计数器组件使用样例

import React from 'react';
import {createStore, bindActionCreators} from 'redux';
import {Provider, connect} fomr 'react-redux';

// store initial state
const initialState = {count: 0};

// reducer
const counter = (state = initialState, action) => {
        switch (action.type){
            case "PLUS_ONE":
                return {count: state.count + 1};
            case "MiNUS_ONE":
                return {count: state.count - 1};
            case "CUSTOM_COUNT":
                return {
                    count: state.count + action.payload.count
                };
            default:
              return state;
        }  
}
// create store
const store = createStore(counter);
// Action creator
function plusOne(){
   return {type: "PLUS_ONE"}
}
function minusOne(){
        return {type: "MINUS_ONE"};
}

export class Counter extends React.Component{
    render(){
        const {count, plusOne, minusOne} = this.props;
        return (
            <div className = "counter">
                <button onClick = {minusOne}>-</button>
                <span>{count}</span>
                <button onClick = {plusOne}>+</button>
             </div>
        );
    }
}


// 将store的state与组件props绑定
function mapStateToProps(state){
    return {
        count: state.count
    };
}

// 将store的action与组件props绑定
function mapDispatchToProps(dispatch){
    return bindActionCreators({plusOne, minusOne}, dispatch)
}


// 通过connect组件将store与counter组件关联
const ConnectedCounter = connect(mapStateToProps, mapDispatchToProps)(Counter) ;

// 返回使用样例
export default class CounterSample extends React.Component{
    render(){
        return (
            // prodiver 基于react context实现,可以让里面的子组件都能获取到store
            <Provider store = {store}>
                <ConnectedCounter/>
            </Provider>
        );
    }
}



http://www.kler.cn/a/135450.html

相关文章:

  • 【安全通信】告别信息泄露:搭建你的开源视频聊天系统briefing
  • 大语言模型:解锁自然语言处理的无限可能
  • 前端-同源与跨域
  • 【嵌入式开发】单片机CAN配置详解
  • vue3+element-plus==> el-form输入响应式失效踩坑!!!!!!!!!!
  • NoSQL数据库与关系型数据库的主要区别
  • 053-第三代软件开发-元对象系统
  • Java中异常的概念、体系结构和分类
  • docker安装elasticsearch,elasticsearch-head
  • 【数字图像处理】Gamma 变换
  • 【Electron】electron-builder打包失败问题记录
  • svn问题集
  • 解决requests 2.28.x版本SSL错误:证书验证失败
  • 【Linux】Linux下的基础IO
  • Redis字典实现
  • Pikachu漏洞练习平台之XXE(XML外部实体注入)
  • C语言——写一个函数,每调用一次这个函数,就会将num的值增加1
  • Java拼图小游戏
  • 数电实验-----实现74LS153芯片扩展为8选1数据选择器以及应用(Quartus II )
  • vue3+ts扩展全局属性
  • Python编程陷阱(九)
  • Java 算法篇-链表的经典算法:判断回文链表、判断环链表与寻找环入口节点(“龟兔赛跑“算法实现)
  • 【信息安全】浅谈SQL注入攻击的概念、原理和防范措施:简单分析六种常见攻击方式
  • ubuntu下载conda
  • 基于RK3588全高端智能终端机器人主板
  • 链动2+1模式:创新营销引领白酒产业新潮流