博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
React 和 Redux 快速开发实战
阅读量:4085 次
发布时间:2019-05-25

本文共 5813 字,大约阅读时间需要 19 分钟。

今天聊一聊 react + redux 环境快速搭建,以及实战一个 TodoList,可能是有史以来最简洁的方法哦,是不是很期待,当时橙子也是很吃惊这样的搭建速度。

本文适合有 react 和 redux 基础的同学看,当然你也可以看完本文去学基础。下面进入正题

快速搭建环境

没错,看过前面博客的同学猜到,我会选择各种 cli 工具,当然你可能猜错了,这里用的不是 create-react-app 这个 star 最多的构建工具。

这里我们用 

需要 node 4.5.0+ & npm 3.0.0+ 即可,首先

git clone https://github.com/davezuko/react-redux-starter-kit.git 
cd
npm installnpm start

没错你已经搭建环境完毕。好快的样子!

此时你可以看到 localhost:3000 的首屏了,welcome 然后一个鸭子,奇怪的首屏,作者说 duck 是 redux 的谐音,好吧。。。

此时可能你已经兴奋的点完了,这个 cli 的全部内容。

先不急看效果,既然是 redux,就要有对应的 chrome 插件,让我们直观的看到 store 的变化。

推荐  ,点开链接,添加至 chrome 即可。

此时开启控制台,找到 Redux 的 tab,会看到如下界面

功能强大,想深入学习的可以看文档,这里我们只关心 Action 和 State 的变化

此时项目在 localhost:3000/counter 这个路由下有个累加器,Increment 每次同步加 1,Double(async) 每次异步乘 2。

异步处理速度慢?不是的看代码会发现这样一段

export const doubleAsync = () => {  return (dispatch, getState) => {    return new Promise((resolve) => {      setTimeout(() => {        dispatch({          type    : COUNTER_DOUBLE_ASYNC,          payload : getState().counter        })        resolve()      }, 200)    })  }}

没错,是一个 200ms 的 setTimeout。

大家印象里,官方文档有说 action 是立即执行的同步函数,我们可以借助中间件的形式实现异步,这里用的是 redux-thunk ,这种方式的确解决了问题,之后的文章还会单独介绍更好的办法。

代码简单过一遍,没什么难点。接下来我们就可以根据这个项目渐进开发了。

实战 TodoList

好,我们首先添加一个路由

src/compoments/Header/Header.js

在 div 标签内最下面添加如下代码

{
' · '}
Todo

src/routes/index.js

对应位置如下修改,添加一个子路由。

import CoreLayout from '../layouts/CoreLayout'import Home from './Home'import CounterRoute from './Counter'import TodoRoute from './Todo'export const createRoutes = (store) => ({  path        : '/',  component   : CoreLayout,  indexRoute  : Home,  childRoutes : [    CounterRoute(store),    TodoRoute(store)  ]})

我们现在还没有 Todo 对应路由的组件,下面在 routes 下创建 Todo 文件夹,然后文件夹结构如下

Todo  |-components  |  |-Todo.js  |  |-containers  |  |-TodoContainer.js  |  |-modules  |  |-todo.js  |  |-index.js

简单解释一下这个目录结构,index.js 是 Todo 作为路由页面的入口文件,components 下放的是模块的视图部分,containers 作为一个容器来绑定组件的 event、 state 和 prop,modules 主要是负责从 action->reducer->newState 的过程。

条例清晰,梳理完结构,看看每个文件都怎么完成的

index.js

import { injectReducer } from '../../store/reducers'export default (store) => ({  path : 'todo',  getComponent (nextState, cb) {    require.ensure([], (require) => {      const Todo = require('./containers/TodoContainer').default      const { itemReducer } = require('./modules/todo')      const { todoListReducer } = require('./modules/todo')      injectReducer(store, { key: 'itemData', reducer: itemReducer })      injectReducer(store, { key: 'todoList', reducer: todoListReducer })      cb(null, Todo)    }, 'todo')  }})

这里将 store 和 reducer 绑定,将 store 注入到 /todo 的路由下的 props 中去

components/Todo.js

import React, { Component } from 'react'export default class Todo extends Component {  render () {    return (      
this.handleChange(e)} />
    { this.props.todoList.map((item, index) => { return
  • {item}
  • }) }
) } handleChange (e) { const node = this.refs.input const text = node.value.trim() this.props.updateItem(text) } handleSubmit (e) { const node = this.refs.input const text = node.value.trim() this.props.addItem(text) this.props.updateItem('') } handleDel (e) { const index = e.target.getAttribute('data-index') this.props.delItem(Number(index)) }}Todo.propTypes = { addItem: React.PropTypes.func.isRequired, itemData: React.PropTypes.string.isRequired, updateItem: React.PropTypes.func.isRequired, delItem: React.PropTypes.func.isRequired, todoList: React.PropTypes.array.isRequired}

就是个简单的 jsx,这里后缀没有写成 .jsx 文件,因为 webpack 配置了解析规则,.js 文件也可以正常解析,这里的 onClick 事件写成了 => 箭头函数的形式,目的是为了锁定 this 的作用域,在 handle 函数内可以拿到 this。

containers/TodoContainer.js

import { connect } from 'react-redux'import { updateItem, addItem, delItem } from '../modules/todo'import Todo from '../components/Todo'const mapDispatchToProps = {  updateItem,  addItem,  delItem}const mapStateToProps = (state) => ({  itemData: state.itemData,  todoList: state.todoList})export default connect(mapStateToProps, mapDispatchToProps)(Todo)

这里通过一个 connect 方法,将组件的 props 进行绑定。

modules/todo.js

export const UPDATE_ITEM = 'UPDATE_ITEM'export const ADD_ITEM = 'ADD_ITEM'export const DELETE_ITEM = 'DELETE_ITEM'export function updateItem (item) {  return {    type: UPDATE_ITEM,    payload: item  }}export function addItem (item) {  return {    type: ADD_ITEM,    payload: item  }}export function delItem (index) {  return {    type: DELETE_ITEM,    payload: index  }}export const actions = {  updateItem,  addItem,  delItem}const ITEM_ACTION_HANDLERS = {  [UPDATE_ITEM]: (state, action) => action.payload}const LIST_ACTION_HANDLERS = {  [ADD_ITEM]: (state, action) => state.concat(action.payload),  [DELETE_ITEM]: (state, action) => state.filter((item, index) => {    return index !== action.payload  })}export function itemReducer (state = '', action) {  const handler = ITEM_ACTION_HANDLERS[action.type]  return handler ? handler(state, action) : state}export function todoListReducer (state = [], action) {  const handler = LIST_ACTION_HANDLERS[action.type]  return handler ? handler(state, action) : state}

这里 reducer 运用两个数组方法 concat 和 filter,分别做拼接和删除操作,这里意遵循 redux 的官方文档在不修改原 state,而是返回新的 state。在底部将两个 reducer 导出,绑定到 index.js 中。完成一个闭环,数据更新完成。

到这里我们的 todoList 完成了。

一边看界面一边看控制台 redux store 的变化吧!代码没有晦涩难懂的点,一个 todoList 也足以说明列表操作的流程,这也是各大框架都以 todoList 为 demo 的原因。

总结

对于复杂的应用 redux 带来的优势不赘述,本文的目的是讲述如何快速开发 react + redux 应用,让大家在配置环境上少踩坑,也通过一个简单的例子,说明我们应该怎么更简单的去使用 redux。动手写起来吧,橙子的文章一般都看不出效果的,亲手实现一遍会有意外收获哦,上面代码也是橙子自己踩过坑后写出来的,各大神有什么建议的地方尽管提出来!感谢阅读。

转载地址:http://ozeni.baihongyu.com/

你可能感兴趣的文章
文件超出大小,进度条监听一直死循环一般的报错
查看>>
数据库xml输出
查看>>
分布式架构高可用架构篇_07_MySQL主从复制的配置(CentOS-6.7+MySQL-5.6)
查看>>
PHP获取真实客户端的真实IP的方法
查看>>
aquery验证
查看>>
IOS5开发-UIScrollView添加单击事件的方法
查看>>
MongoDB-3.4搭建副本集
查看>>
《疯狂Java讲义》(五)---- 数据类型
查看>>
CodeBlocks+MinGW编写实现IP地址的增量输出
查看>>
交换机主要参数详解
查看>>
做教育管理系统时 遇到的一些问题 总结 培训机构管理系统 中小学管理系统 托管系统 语数英物化...
查看>>
多行溢出隐藏
查看>>
第5周-继承、多态、抽象类与接口
查看>>
virtual hust 2013.6.21 NEFU 挑战编程----数论 C - Euclid Problem
查看>>
php日期函数坑点
查看>>
Mybatis 注解 @Many 实现 递归菜单获取
查看>>
在ubuntu上搭建开发环境6---安装和使用vim及其插件(Pathogen和NERDTree)
查看>>
python_79_模块定义导入优化
查看>>
第五周:统计学
查看>>
备忘录模式
查看>>