本篇文章主要介绍了react+redux的升级版todoList的实现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
又是很久不写博客了,最近在用蚂蚁金服的ant-design-pro写毕设,写着写着写不下去了,很多东西都不理解,不得不说大神写出来的东西都是需要花学习成本的,或者底子好,对于React新手来说就有点难了。所以就老老实实的认真看了下Redux到底如何使用,在这里推荐一下自己最近在看的书,写的算是比较详细的:《深入React技术栈》。废话不多说,今天就分享下自己如何使用redux来实现一个todoList的,希望对想要用redux的你会有所帮助。
(为什么叫升级版呢?因为之前写过一个没有用redux的todoList)
该项目使用react官方的create-react-app架构,每个目录可以根据自己的需求来划分。下面解释下每个目录的内容和功能。
public:主要放静态资源(入口html文件,图片资源,JSON文件等);
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/views/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 ( <List {...this.props} /> ); } } 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 ( <Provider store={store}> <Router> <Route path="/" component={BasicLayout} /> </Router> </Provider> ); } } export default RouterApp;
Provider是react-redux的一个组件,作用就是用来将store传入整个应用。
上面是我整理给大家的,希望今后会对大家有帮助。
相关文章:
以上是如何通过react+redux升级版来实现todoList的详细内容。更多信息请关注PHP中文网其他相关文章!

在react中,canvas用于绘制各种图表、动画等;可以利用“react-konva”插件使用canvas,该插件是一个canvas第三方库,用于使用React操作canvas绘制复杂的画布图形,并提供了元素的事件机制和拖放操作的支持。

React不是双向数据流,而是单向数据流。单向数据流是指数据在某个节点被改动后,只会影响一个方向上的其他节点;React中的表现就是数据主要通过props从父节点传递到子节点,若父级的某个props改变了,React会重渲染所有子节点。

在react中,antd是基于Ant Design的React UI组件库,主要用于研发企业级中后台产品;dva是一个基于redux和“redux-saga”的数据流方案,内置了“react-router”和fetch,可理解为应用框架。

因为在react中需要利用到webpack,而webpack依赖nodejs;webpack是一个模块打包机,在执行打包压缩的时候是依赖nodejs的,没有nodejs就不能使用webpack,所以react需要使用nodejs。

react是组件化开发;组件化是React的核心思想,可以开发出一个个独立可复用的小组件来构造应用,任何的应用都会被抽象成一颗组件树,组件化开发也就是将一个页面拆分成一个个小的功能模块,每个功能完成自己这部分独立功能。

react和reactdom的区别是:ReactDom只做和浏览器或DOM相关的操作,例如“ReactDOM.findDOMNode()”操作;而react负责除浏览器和DOM以外的相关操作,ReactDom是React的一部分。

在react中,forceupdate()用于强制使组件跳过shouldComponentUpdate(),直接调用render(),可以触发组件的正常生命周期方法,语法为“component.forceUpdate(callback)”。

react中没有双向绑定;react的设计思想就是单向数据流,没有双向绑定的概念;react是view层,单项数据流只能由父组件通过props将数据传递给子组件,满足了view层渲染的要求并且更易测试与控制,所以在react中没有双向绑定。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

EditPlus 中文破解版
体积小,语法高亮,不支持代码提示功能

安全考试浏览器
Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

螳螂BT
Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。