• 【React自制全家桶】九、Redux入手


    一、React项目中为什么要用Redux

      上图:

    左图当使用纯React开发稍微大点的项目,因为React数据是瀑布式的,只能通过父子组件传递数据,所以实现关系不大的两React的组件之间的数据传递就会让你非常难受,操作起来非常复杂。如右图,由此应运而生了Redux数据流框架,专门解决数据流问题,

    Redux的基本原理就是React的所有组件涉及到的数据全部都存储在共用的Store中,这样所有组件都可以通过Store来改动数据和获取数据,非常方便。

    二、Redux安装

    在已经安装yarn的前提下

    yarn add redux
    

      

    三、Redux工作流讲解

    先上图:

    为了方便理解,我将一个redux的操作流程视为从图书馆取书的流程:

    1、React Components(借书人)

    2、说借一本《React全栈》书(Action Creations就是代表需要进行的操作)

    3、Store(图书馆管理员)听到了这句话

    4、从reducers(记书本)中查询书在哪放着

    5、Store(图书馆管理员)查到(即reducers返回newState)

    6、Store(图书馆管理员)将书交给React Components(借书人)(即:将改动后的state发给React Components(借书人))

    四、Redux使用入门

    1、使用谷歌浏览器下载浏览器rudux插件(建议开启科学上网后下载安装)

    2、在src目录下创建store文件夹

    3、在store文件夹下创建index.js文件作为redux的入口文件

    import {createStore} from 'redux';
    // 引入reducer
    import reducer from './reducer';
    
    const store = createStore(
        reducer,
        // 显示redux调试工具
        window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
    );
    
    export default store;
    

      

    4、在store文件夹下创建reducer.js文件作为数据

    import {CHANGE_INPUT_VALUE , ADD_TODO_ITEM , DELETE_TODO_ITEM} from './actionTypes';
    
    const defaultState = {
        inputValue : "",
        list: []
    };
    
    //reducers可以接收state但是绝不能修改state
    //reducers不能有异步操作也不能有与时间相关的操作,也不能对接收的参数进行修改
    //返回纯函数,纯函数指的是:给定固定输入,则输出固定,而且不会有任何副作用
    export default (state = defaultState,action) => {
        // state是上一个store中存储的数据,action是用户发过来的操作请求
        // 1、JSON.parse()用于从一个字符串中解析出json对象
        // 2、JSON.stringify()用于从一个对象解析出字符串
        if (action.type === CHANGE_INPUT_VALUE) {
            // state深拷贝
            const newState = JSON.parse(JSON.stringify(state));
            newState.inputValue = action.value;
            return newState;
        }
        if (action.type === ADD_TODO_ITEM) {
            // state深拷贝
            const newState = JSON.parse(JSON.stringify(state));
            newState.list.push(newState.inputValue);
            newState.inputValue = '';
            return newState;
        }
        if (action.type === DELETE_TODO_ITEM) {
            // state深拷贝
            const newState = JSON.parse(JSON.stringify(state));
            newState.list.splice(action.index, 1);
            return newState;
        }
        return state;
    }
    

      

    5、核心组件中导入store

    import React,{Component} from 'react';
    import 'antd/dist/antd.css';
    import {Input, Button, List} from 'antd';
    import store from './store/index';
    import {getInputChangeAction, getAddItemAction, getDeleteItemAction} from './store/actionCreators'
    // import {CHANGE_INPUT_VALUE , ADD_TODO_ITEM , DELETE_TODO_ITEM} from './store/actionTypes';
    
    class TodoList extends Component{
    
        constructor(props){
            super(props);
            this.state = store.getState();
            this.handleInputChange = this.handleInputChange.bind(this);
            this.handleStoreChange = this.handleStoreChange.bind(this);
            this.handleBtnClick = this.handleBtnClick.bind(this);
            // 监听store中数据的变化,改变则通过handleStoreChange()函数重新渲染
            store.subscribe(this.handleStoreChange)
        }
    
        render(){
            return(
                <div style={{margin:'30px'}}>
                    <div>
                        <Input
                            type="text"
                            value={this.state.inputValue}
                            placeholder='todo info'
                            style={{'300px',marginRight:'10px'}}
                            onChange={this.handleInputChange}
                        />
                        <Button type="primary" onClick={this.handleBtnClick}>提交</Button>
                    </div>
                    <div>
                        <List
                            style={{'300px',marginTop:'10px'}}
                            bordered
                            // 数据源
                            dataSource={this.state.list}
                            renderItem={(item,index) => (<List.Item onClick={this.handleItemDelete.bind(this,index)}>{item}</List.Item>)}
                        />
                    </div>
                </div>
            )
        }
    
        // 输入框改变
        handleInputChange(e){
            const action = getInputChangeAction(e.target.value);
            // 将action派发给store
            store.dispatch(action);
        }
    
        // 数据重新获取并渲染
        handleStoreChange(){
            // store.getState()从store中重新取数据
            // this.setState()更新数据
            this.setState(store.getState())
        }
    
        // 点击后增添数据
        handleBtnClick(){
            // 创建action对象
            const action = getAddItemAction();
            // 将action发给store
            store.dispatch(action);
        }
    
        handleItemDelete(index){
            const action = getDeleteItemAction(index);
            store.dispatch(action);
        }
    
    }
    
    export default TodoList;
    

      

    6、升级——store中创建actionCreators

    import {ADD_TODO_ITEM, CHANGE_INPUT_VALUE, DELETE_TODO_ITEM} from "./actionTypes";
    
    export const getInputChangeAction = (value) => ({
        type : CHANGE_INPUT_VALUE,
        value
    });
    
    export const getAddItemAction = () => ({
        type : ADD_TODO_ITEM
    });
    
    export const getDeleteItemAction = (index) => ({
        type : DELETE_TODO_ITEM,
        index
    });
    

      

    7、升级——store中创建actionTypes

    export const CHANGE_INPUT_VALUE = 'change_input_value';
    export const ADD_TODO_ITEM = 'add_todo_item';
    export const DELETE_TODO_ITEM = 'delete_todo_item';
    

      

  • 相关阅读:
    (原)Lazarus 异构平台下多层架构思路、DataSet转换核心代码
    (学)新版动态表单研发,阶段成果3
    (学) 如何将 Oracle 序列 重置 清零 How to reset an Oracle sequence
    (学)XtraReport WebService Print 报错
    (原)三星 i6410 刷机 短信 无法 保存 解决 办法
    (原) Devexpress 汉化包 制作工具、测试程序
    linux下网络配置
    apache自带ab.exe小工具使用小结
    Yii::app()用法小结
    PDO使用小结
  • 原文地址:https://www.cnblogs.com/piaobodewu/p/9458213.html
Copyright © 2020-2023  润新知