Redux实现数据统一管理 详解

1、什么是Redux

Redux 是React生态中重要的组成部分。很多人都说,简单的应用可以不用此工具。但是我个人认为,中小型应用使用的话,可以使文件结构更加规范,代码可读性更强。因为React提出将展示组件与容器组件分离的思想,所以降低了React 与Redux之间的耦合度。
在这里插入图片描述
Redux是一个流行的JavaScript框架,为应用程序提供一个可预测的状态容器。Redux基于简化版本的Flux框架,Flux是Facebook开发的一个框架。在标准的MVC框架中,数据可以在UI组件和存储之间双向流动,而Redux严格限制了数据只能在一个方向上流动。 见下图:

图片描述

在Redux中,所有的数据(比如state)被保存在一个被称为store的容器中 → 在一个应用程序中只能有一个。store本质上是一个状态树,保存了所有对象的状态。任何UI组件都可以直接从store访问特定对象的状态。要通过本地或远程组件更改状态,需要分发一个action分发在这里意味着将可执行信息发送到store。当一个store接收到一个action,它将把这个action代理给相关的reducerreducer是一个纯函数,它可以查看之前的状态,执行一个action并且返回一个新的状态。

Redux的运行原理

img

store中重要的方法

img

2、配置Redux

配置Redux开发环境的最快方法是使用create-react-app工具。在开始之前,确保已经安装并更新了nodejsnpm

npm install redux

创建store目录,在store目录下新建index.js文件,键入以下内容:

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

const store = createStore(reducer);

export default store;

在store目录下创建reducer.js文件,键入以下内容:

const defaultState = {
    inputValue:'',
    list:[]
}

//reducer可以接收state,但是不能修改state
export default (state = defaultState,action) => {
    return state;
}

在组件中就可以使用store的数据

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

class TodoList extends Component{

    constructor(props){
        super(props);
        this.state = store.getState();
        this.handleStoreChange = this.handleStoreChange.bind(this);
        store.subscribe(this.handleStoreChange);
    }
    
    handleStoreChange(){
        this.setState(store.getState());
    }

    render(){
        return (
            <div>
                <input type='text' value={this.state.inputValue}/>
                <button onClick={this.handleClick}>提交</button>
                <ul>
                    {this.state.list.map((item,index)=>{
                        return (
                            <li key={index}>{item}</li>
                        );
                    })}
                </ul>
            </div>
        );
    }
}

export default TodoList;

3、TodoList案例

TodoList.js

import React,{Component} from 'react';
import store from './store/index';
import {DELETE_TODO_ITEM,CHANGE_INPUT_VALUE,ADD_TODO_ITEM} from './store/actionType'

class TodoList extends Component{

    constructor(props){
        super(props);
        this.state = store.getState();
        this.handleChange = this.handleChange.bind(this);
        this.handleStoreChange = this.handleStoreChange.bind(this);
        this.handleClick = this.handleClick.bind(this);
        store.subscribe(this.handleStoreChange);

    }

    handleChange(e){
        const action = {
            type:CHANGE_INPUT_VALUE,
            value:e.target.value
        }
        store.dispatch(action);
    }

    handleStoreChange(){
        this.setState(store.getState());
    }

    handleClick(){
        const action = {
            type:ADD_TODO_ITEM
        }
        store.dispatch(action);
    }

    handleClickItem(index){
        const action = {
            type:DELETE_TODO_ITEM,
            index:index
        }
        store.dispatch(action);
    }

    render(){
        return (
            <div>
                <input type='text' value={this.state.inputValue} onChange={this.handleChange} />
                <button onClick={this.handleClick}>提交</button>
                <ul>
                    {this.state.list.map((item,index)=>{
                        return (
                            <li key={index} onClick={this.handleClickItem.bind(this,index)}>{item}</li>
                        );
                    })}
                </ul>
            </div>
        );
    }
}

export default TodoList;

store/index.js

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

const store = createStore(reducer);

export default store;

store/reducer.js

import {DELETE_TODO_ITEM,CHANGE_INPUT_VALUE,ADD_TODO_ITEM} from './actionType'

const defaultState = {
    inputValue:'',
    list:[]
}

//reducer可以接收state,但是不能修改state
export default (state = defaultState,action) => {
    console.log(state,action);
    if(action.type === CHANGE_INPUT_VALUE){
        const newState = state;
        newState.inputValue = action.value;
        return newState;
    }
    if(action.type === ADD_TODO_ITEM){
        const newState = state;
        newState.list.push(newState.inputValue);
        newState.inputValue = '';
        return newState;
    }
    if(action.type === DELETE_TODO_ITEM){
        const newState = state;
        newState.list.splice(action.index,1);
        return newState;
    }
    
    return state;
}

store/actionType.js

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

核心API:

  • createStore 创建store
  • store.dispatch 派发action,把数据上传到Store中
  • store.getState 获取store中所有的数据内容,但是Store中的数据发生变化时,组件不会知道
  • store.subscribe 监听Store中的数据变化,Store中的数据一旦发生变化,该方法就会被执行
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章