Redux 使用指南(todoList 案例)

前言

Redux 是一个状态管理框架,通常与 React 结合使用,来实现 React 的状态集中统一化管理。但是与 Vuex 不同的是,Redux 也可以独立使用。并不专职为 React 服务。而 Vuex 主要是为 Vue 专门制定的状态管理工具。
在使用前执行npm install redux react-redux下载 Redux。

案例需求

实现一个 todoList (代办事项管理),包含的功能有:

  1. 添加待办事项;
  2. 编辑待办事项状态(将待办事项置为已完成或者未完成);
  3. 删除待办事项;
  4. 查询待办事项(按状态已完成/未完成/所有查询)。

实现思路

一共分为三个组件实现该功能。
TodoList.js 为核心组件父组件,提供添加待办事项的方法。
TodoItem.js 为任务项组件,渲染任务项视图,提供修改待办事项状态及删除任务的方法。
FilterItem.js 为过滤器组件,渲染过滤项视图。提供筛选待办事项的方法。

第一步:定义 Action

action 定义用户行为类型以及该行为所需要的参数。在整个 todolist 程序中,抽象出来的用户行为有:用户添加待办事项、用户改变待办事项状态、用户删除待办事项、用户筛选待办事项。

 let count = 0;
let actions = {
    //添加任务
    addTodo: (text)=>{
        return {type: 'add', payload:{text:text,id:++count,done:false}};
    },
    //删除任务
    delTodo: (index)=>{
        return {type: 'del', index};
    },
    //修改任务状态
    changeStatus:(item)=>{
        return {type: 'change', item};
    },
    //过滤任务列表
    onFilter:(flag)=>{
        return {type: 'filter', flag};
    }
};
export default actions;

第二步:定义 Reducer

reduce 表示根据用户行为,响应不同的状态,然后根据状态更新视图。在整个 todolist 程序中,抽象出来的响应状态有:

  1. 新增/删除/更改代办事项之后更新待办事项列表,定义 todosReducers;
const todosReducer = (state = [],action)=>{
    switch (action.type) {
        case 'add':
            state = [...state, action.payload];
            return [...state];
        case 'del':
            state.splice(action.index,1);
            return [...state];
        case 'change':
            action.item.done = !action.item.done;
            return [...state];
        default:
            return state;
    }
};
export default todosReducer;
  1. 根据用户的筛选条件查询出符合条件的待办事项列表,定义 filterReducers。
const filterReducer = (state ="all", action)=>{
    switch (action.type) {
        case 'filter':
            if(action.flag == 'all'){
                state = 'all';
            };
            if(action.flag == 'completed'){
                state = true;
            };
            if(action.flag == 'uncompleted'){
                state = false;
            };
            return state;
        default:
            return state;
    }
};
export default filterReducer;

第三步:整合 Reducer

通过 combineReducers 方法将单个的 Reducer 整合到一起,定义allReducers。

import {combineReducers} from 'redux';
import filterReducer from './filterReducer';
import todosReducer from './todosReducer';
const allReducers  = combineReducers({filter:filterReducer,todos:todosReducer});
export default allReducers;

第四步:定义 Store

store 是储存状态的仓库,所有的 state ,reduce ,跟 redux 相关的 API 等都是储存在 store 中。

import {createStore} from 'redux';
import allReducers from './allReducers';
let store = createStore(allReducers);
export default store;

第五步:处理业务逻辑

  1. TodoList.js 为核心组件父组件,渲染了待办事项列表和过滤器,并且提供添加待办事项的方法。

TodoList.js

import React from 'react';
import TodoItem from './component/TodoItem';
import Filter from './component/FilterItem';
import {connect} from 'react-redux';
import actions from './store/actions';
class TodoList extends React.Component {
    constructor(props) {
        super(props);
        this.status =[
            {label:"所有",flag:"all"},
            {label:"已完成",flag:"completed"},
            {label:"未完成",flag:"uncompleted"},
        ]
    }
    add(){
        var value = this.refs.input.value;
        const {addTodo} = this.props;
        addTodo(value);
    }
    render() {
        const {todos} = this.props;
        return <div>
            <input type="text" ref="input"/><button onClick={()=>this.add()}>添加任务</button>
            {todos.map((item,index)=>{
                return <TodoItem
                    item={item}
                    key={index}
                    index={index}
                />
            })}
            <div className="list-mt-20">
                {this.status.map((item,index)=>{
                    return <Filter
                        item={item}
                        key={index}
                    />
                })}
            </div>
        </div>
    }
}
const mapStateToProps = (state)=>{
    return{
        todos:state.todos
    };
};
const mapDispatchToProps = (dispatch)=>{
    return {
        addTodo:(val)=>dispatch(actions.addTodo(val))
    }
};
export default connect(mapStateToProps,mapDispatchToProps)(TodoList);
  1. TodoItem.js 为任务项组件,渲染单条任务项视图,提供修改待办事项状态及删除任务的方法。

TodoItem.js

import React from 'react';
import '../index.css';
import {connect} from 'react-redux';
import actions from '../store/actions';
class TodoItem extends React.Component {
    constructor(props) {
        super(props);
    }
    del(index){
        const {delTodo} = this.props;
        delTodo(index);
    }
    changeStatus(item){
        const {changeStatus} = this.props;
        changeStatus(item);
    }
    render() {
        const {item,index,filter} = this.props;
        return(
            <div>{filter == 'all'?<div><span className={item && item.done?'list-line':''} onClick={() => this.changeStatus(item)}>{item.text}</span>
                    <button onClick={() => this.del(index)}>删除</button>
                </div>:(filter == item.done?<div><span className={item && item.done?'list-line':''} onClick={() => this.changeStatus(index)}>{item.text}</span>
                    <button onClick={() => this.del(index)}>删除</button>
                </div>:null)}
            </div>
        )
    }
}
const mapStateToProps  = (state)=>{
    return{
        filter:state.filter,
        todos:state.todos,
    };
};
const mapDispatchToProps  = (dispatch)=>{
    return {
        delTodo:(index)=>dispatch(actions.delTodo(index)),
        changeStatus:(item)=>dispatch(actions.changeStatus(item)),
    }
};
export default connect(mapStateToProps,mapDispatchToProps)(TodoItem);
  1. FilterItem.js 为过滤器组件,渲染过滤项视图。提供筛选待办事项的方法。

FilterItem.js

import React from 'react';
import '../index.css';
import {connect} from 'react-redux';
import actions from '../store/actions';
class Filter extends React.Component {
    constructor(props) {
        super(props);
    }
    filter(flag){
        const {onFilter} = this.props;
        if(onFilter){
            onFilter(flag);
        }
    }
    render() {
        const {item} = this.props;
        return<span className="filter-mr-20" onClick={()=>this.filter(item.flag)}>{item.label}</span>
    }
}
const mapStateToProps = (state)=>{
    return{
        filter:state.filter,
    };
};
const mapDispatchToProps = (dispatch)=>{
    return {
        onFilter:(flag)=>dispatch(actions.onFilter(flag))
    }
};
export default connect(mapStateToProps,mapDispatchToProps)(Filter);

第六步:注意事项

项目中所用到的 connect 方法来自于 Redux 库。该方法是一个高阶组件,接收当前业务逻辑需要用到的 state 和 props 作为第一阶参数,接收当前业务组件作为第二阶参数。处理之后的结果是将所有的 state 和 props 作为 props 注入到当前业务组件中。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值