redux 工作中小技巧-改写TodoList

写Redux Action的时候,我们写了很多Action的派发,产生了很多Action Types,如果需要Action的地方我们就自己命名一个Type,会出现两个基本问题:

(1)这些Types如果不统一管理,不利于大型项目的复用,设置会产生冗余代码

(2)因为Action里的Type,一定要和Reducer里的type一一对应在,所以这部分代码或字母写错后,浏览器里并没有明确的报错,这给调试带来了极大的困难。

技巧一:

Action Type单独拆分出一个文件。在src/store文件夹下面,新建立一个actionTypes.js文件,然后把Type集中放到文件中进行管理。

export const CHANGE_INPUT = 'changeInput';
export const ADD_ITEM = 'addItem';
export const DELETE_ITEM = 'deleteItem';

技巧二:

目前ToDoList组件里有很多Action,并且分散在程序的各个地方,如果庞大的工程,这势必会造成严重的混乱,就把所有的Redux Action放到一个文件里进行管理。

编写actionCreators.js文件

src/store文件夹下面,建立一个心的文件actionCreators.js,先在文件中引入上节课编写actionTypes.js文件。

import { CHANGE_INPUT, ADD_ITEM, DELETE_ITEM } from './actionTypes';

export const changeInputAction = (value) => ({
    type: CHANGE_INPUT,
    value
})

export const addItemAction = () => ({
    type: ADD_ITEM,
})

export const deleteItemAction = (index) => ({
    type: DELETE_ITEM,
    index
})

改写之后reducer.js文件

import { CHANGE_INPUT, ADD_ITEM, DELETE_ITEM } from './actionTypes';

const defaultState = {
    inputValue:'Write Something',
    list:[
        '早8点开晨会,分配今天的代码任务',
        '早9点和项目经理开需求沟通会',
        '晚5点组织人员进行Review代码'
    ]

};
export default( state = defaultState, action ) => {
    console.log(state,action);
    //Reducer里只能接收state,不能改变state
    if(action.type === CHANGE_INPUT){
        let newState=JSON.parse(JSON.stringify(state));  //深拷贝
        newState.inputValue=action.value;
        return newState;
    }

    if(action.type === ADD_ITEM){
        let newState=JSON.parse(JSON.stringify(state));  //深拷贝
        newState.list.push(newState.inputValue);
        newState.inputValue='';  //增加完设置input内容为空
        return newState;
    }

    if(action.type === DELETE_ITEM){
        let newState=JSON.parse(JSON.stringify(state));  //深拷贝
        newState.list.splice(action.index,1);
        return newState;
    }
    return state;
}

TodoList.js文件

import React, {Component} from 'react';
import 'antd/dist/antd.css';
import {Input, Button, List} from 'antd';
import store from './store';
import {changeInputAction, addItemAction, deleteItemAction} from './store/actionCreators';


class TodoList extends Component {
    constructor(props){
        super(props);
        this.state=store.getState();   //store.getState()方法可以拿到reducer.js中的数据
        this.changeInputvalue=this.changeInputvalue.bind(this);
        this.storeChange=this.storeChange.bind(this);
        this.clickBtn=this.clickBtn.bind(this);
        store.subscribe(this.storeChange);   //如果想要state的状态发生变化,订阅模式必须写上

    }
    changeInputvalue(e){
        const action=changeInputAction(e.target.value);
        store.dispatch(action);
    }

    clickBtn(){
        const action=addItemAction();
        store.dispatch(action);   
    }

    deleteItem(index){
        const action=deleteItemAction(index);
        store.dispatch(action); 
    }

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


    render(){
        return(
            <div style={{margin:'10px'}}>
                <div>
                    <Input 
                    placeholder={this.state.inputValue} 
                    style={{width:'250px', marginRight:'10px'}}
                    onChange={this.changeInputvalue}
                    value={this.state.inputValue}
                    />
                    <Button type="primary"
                    onClick={this.clickBtn}>增加</Button>
                    <div style={{margin:'10px',width:'300px'}}>
                        <List
                            bordered
                            dataSource={this.state.list}
                            renderItem={(item,index)=>(<List.Item onClick={this.deleteItem.bind(this,index)}>{item}</List.Item>)}
                        />
                    </div>
                </div>
            </div>
        )
    }
}

export default TodoList;

Redux填三个坑:

(1)store必须是唯一的,多个store是坚决不允许,只能有一个store空间

现在看TodoList.js的代码,就可以看到,这里有一个/store/index.js文件,只在这个文件中用createStore()方法,声明了一个store,之后整个应用都在使用这个store

(2)只有store能改变自己的内容,Reducer不能改变

很多新手小伙伴会认为把业务逻辑写在了Reducer中,那改变state值的一定是Reducer,其实不然,在Reducer中我们只是作了一个返回,返回到了store中,并没有作任何改变。

Reudcer只是返回了更改的数据,但是并没有更改store中的数据,store拿到了Reducer的数据,自己对自己进行了更新

(3)Reducer必须是纯函数

纯函数定义:如果函数的调用参数相同,则永远返回相同的结果。它不依赖于程序执行期间函数外部任何状态或数据的变化,必须只依赖于其输入参数。

reducer.js返回结果,是完全由传入的参数stateaction决定的,这就是一个纯函数。这个在实际工作中是如何犯错的?比如在Reducer里增加一个异步ajax函数,获取一些后端接口数据,然后再返回,这就是不允许的(包括你使用日期函数也是不允许的),因为违反了调用参数相同,返回相同的纯函数规则。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值