react+redux的升级版todoList的实现

网友投稿 346 2023-03-05


react+redux的升级版todoList的实现

又是很久不写博客了,最近在用蚂蚁金服的ant-design-pro写毕设,写着写着写不下去了,很多东西都不理解,不得不说大神写出来的东西都是需要花学习成本的,或者底子好,对于React新手来说就有点难了。所以就老老实实的认真看了下Redux到底如何使用,在这里推荐一下自己最近在看的书,写的算是比较详细的:《深入React技术栈》。废话不多说,今天就分享下自己如何使用redux来实现一个todoList的,希望对想要用redux的你会有所帮助。

(为什么叫升级版呢?因为之前写过一个没有用redux的todoList)

该项目使用react官方的create-react-app架构,每个目录可以根据自己的需求来划分。下面解释下每个目录的内容和功能。

public:主要放静态资源(入口html文件,图片资源,jsON文件等http://);

src/component:不同的组件;

src/layouts:整个页面的基本架构,主要就是Nav,Footer,Content。Nav里面显示User和Notice的数据,Content中实现页面路由的切换,Footer固定不变;

src/redux:

--src/redux/configureStore:生成整个应用的store;

--src/redux/reducers:所有reducer的集合;

src/routes:页面的整体路由;

src/utils:自己封装的工具;

views:存放项目中所要展示的所有页面;

index:整个项目的入口文件;

二. 具体实现

1. 整个应用中store中应存储什么数据?

const initialState = {

taskListData: { //任务列表

loading: false,

error: false,

taskList: [],

},

userData: { //用户信息

loading: false,

error: false,

user: {},

},

noticeListData: { //通知列表

loading: false,

error: false,

noticeList: [],

},

taskData: { //任务详情,在详情页使用

loading: false,

error: false,

task: {},

}

};

2. reducer的分布:

每个state对应一个reducer,所以一共需要四个reducer,在src/redux/reducers中将所有的reducer合并,并且注意每个reducer的名字要和state同名:

/*redux/reducers.js*/

import { combineReducers } from 'redux';

import userReducer from '../component/User/indexRedux';

import noticeReducer from '../component/Notice/indexRedux';

import todoListReducer from '../views/TodoList/indexRedux';

import taskReducer from '../views/Detail/indexRedux';

export default combineReducers({

userData: userReducer,

noticeListData: noticeReducer,

taskListData: todoListReducer,

taskData: taskReducer,

});

每个state都对应一个reducer,所以和state一样,reducer应在放在最顶级的父级组件的目录中,所以将taskListData的reducer放在src/viewsTEjYl/TodoList中,其他同理,代码如下:

/*views/TodoList/indexRedux.js*/

const taskListData = {

loading: true,

error: false,

taskList: []

};

//不同的action;

const LOAD_TASKLIST = 'LOAD_TASKLIST';

const LOAD_TASKLIST_SUCCESS = 'LOAD_TASKLIST_SUCCESS';

const LOAD_TASKLIST_ERROR = 'LOAD_TASKLIST_ERROR';

const ADD_TASK = 'ADD_TASK';

const UPDATE_TASK = 'UPDATE_TASK';

const DELETE_TASK = 'DELETE_TASK';

function todoListReducer (state = { taskListData }, action) {

switch(action.type) {

case LOAD_TASKLIST: {

return {

...state,

loading: true,

error: false,

}

}

case LOAD_TASKLIST_SUCCESS: {

return {

...state,

loading: false,

error: false,

taskList: action.payload,

};

}

case LOAD_TASKLIST_ERROR: {

return {

...state,

loading: false,

error: true

};

}

case UPDATE_TASK: {

const index = state.taskList.indexOf(

state.taskList.find(task =>

task.id === action.payload.id));

console.log(index);

state.taskList[index].status = !state.taskList[index].status;

return {

...state,

taskList: state.taskList,

};

}

case DELETE_TASK: {

const index = state.taskList.indexOf(

state.taskList.find(task =>

task.id === action.payload.id));

state.taskList.splice(index, 1);

return {

...state,

taskList: state.taskList,

};

}

case ADD_TASK: {

let len = state.taskList.length;

let index = len > 0 ? len - 1 : 0;

let lastTaskId = index !== 0 ? state.taskList[index].id : 0;

state.taskList.push({

id: lastTaskId + 1,

name: action.payload.name,

status: false,

});

return {

...state,

taskList: state.taskList,

}

}

default: {

return state;

}

}

}

export default todoListReducer;

3. action creator的分布:

每个动作都代表一个action,action由组件发出,所以将action creator单独一个文件,放在组件目录中。例如:ListItem组件的action creator:

/*ListItem/indexRedux.js*/

//处理更新任务状态后和删除任务后的taskList的状态;

const UPDATE_TASK = 'UPDATE_TASK';

const DELETE_TASK = 'DELETE_TASK';

//action creator,更新和删除任务

export function updateTask (task) {

return dispatch => {

dispatch({

type: UPDATE_TASK,

payload: task,

});

}

}

export function deleteTask (task) {

return dispatch => {

dispatch({

type: DELETE_TASK,

payload: task,

});

}

}

三. 如何将redux和组件连接

react-redux提供了connect方法,将state和action creator绑在组件上,然后在组价内部以props的方式获取。下面是TodoList页面的具体实现:

import React, { Component } from 'react';

import { connect } from 'react-redux';

import { bindActionCreators } from 'redux';

import List from '../../component/List';

import { loadTaskList } from '../../component/List/indexRedux';

import { updateTask, deleteTask } from '../../component/ListItem/indexRedux';

import { addTask } from '../../component/SubmitDialog/indexRedux';

class TodoList extends Component {

render () {

return (

);

}

}

export default connect( state => {

return {

loading: state.taskListData.loading,

error: state.taskListData.error,

taskList: state.taskListData.taskList,

};

}, dispatch => {

return {

loadTaskList: bindActionCreators(loadTaskList, dispatch),

updateTask: bindActionCreators(updateTask, dispatch),

deleteTask: bindActionCreators(deleteTask, dispatch),

addTask: bindActionCreators(addTask, dispatch),

};

})(TodoList);

connect方法有四个参数,这里主要说下前两个参数:

(1)mapStateToProps:参数为state,返回页面所需要的所有state;

(2)mapDispatchToProps:参数为dispatch,返回页面所要使用的异步回调函数。

眼明手快的你肯定看到了,我们从redux包中导出了bindActionCreators方法,该方法将dispatch和action creator绑定,用来触发action。

四. 异步的action creator如何触发呢?

因为每个action creator都是异步函数,我们传给组件的只是函数的声明,所以就要引入我们的中间件,只用在生成store时加入就行了:

/*redux/configureStore.js*/

import { createStore, applyMiddleware } from 'redux';

import thunk from 'redux-thunk';

import reducers from './reducers';

const initialState = {

taskListData: {

loading: false,

error: false,

taskList: [],

},

userData: {

loading: false,

error: false,

user: {},

},

noticeListData: {

loading: false,

error: false,

noticeList: [],

},

taskData: {

loading: false,

error: false,

task: {},

}

};

let enhancer = applyMiddleware(thunk);

let store = createStore(

reducers,

initialState,

enhancer,

);

export default store;

在上面的代码中thunk就是一个中间件,我们将引入的中间件传入applyMiddleware就可以了。

五. store在哪里传入组件呢?

我们肯定会想到,store在整个应用中都存在,所以应该在整个应用的最顶层,对于一般项目而言,当然就是最顶端的路由了:

import React, { Component } from 'react';

import { BrowserRouter as Router, Route } from 'react-router-dom';

import { Provider } from 'react-redux';

import BasicLayout from '../layouts';

import store from '../redux/configureStore';

class RouterApp extends Component {

render () {

return (

);

}

}

export default RouterApp;

Provider是react-redux的一个组件,作用就是用来将store传入整个应用。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:在线的api文档管理系统(在线的api文档管理系统有哪些)
下一篇:微信接口设计(微信接口45009)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~