内容简介:Action 本质上是 JavaScript 普通对象。action 内必须使用一个字符串类型的 type 字段来表示将要执行的动作,但是这样有多少action就需要写多少action,所以这里需要action creator, 这个action构造函数返回一个js对象,当然这里在处理异步数据的时候需要返回一个函数,此时需要用到中间件。reducer具体定义可以看redux自述中的定义,由于demo太简单,拆分合并reducer大家自己看吧,这里主要介绍redux在react中的工作流程。 这里要注意re
- 通过create-react-app快速搭建react项目
- 安装依赖npm install redux react-redux redux-thunk --save (redux-thunk是处理异步数据流的中间件)
- 更改,新建项目目录
- 效果图
Demo开始
编写redux相关内容
action
export const Increment = 'increment' export const Decrement = 'decrement' /*action creator action构造函数*/ export const increment = (counterIndex) => { type:Increment, counterIndex } export const decrement = (counterIndex) => ({ type: Decrement, counterIndex }) 复制代码
Action 本质上是 JavaScript 普通对象。action 内必须使用一个字符串类型的 type 字段来表示将要执行的动作,但是这样有多少action就需要写多少action,所以这里需要action creator, 这个action构造函数返回一个js对象,当然这里在处理异步数据的时候需要返回一个函数,此时需要用到中间件。
reducer
import { Increment, Decrement } from '../Action' export default (state,action) => { const {counterIndex} = action switch (action.type) { case Increment: return {...state, [counterIndex]:state[counterIndex]+1} case Decrement: return {...state, [counterIndex]:state[counterIndex]-1} default: return state } } 复制代码
reducer具体定义可以看redux自述中的定义,由于demo太简单,拆分合并reducer大家自己看吧,这里主要介绍redux在react中的工作流程。 这里要注意reducer是个纯函数,不能更改state,这里返回的新state可以使用Object.assign 以及 es6的对象扩展符。
store
import {applyMiddleware, createStore} from 'redux' import thunk from 'redux-thunk' import reducer from '../Reducer' const initValue={ 'First':1, 'Second':5, 'Third':6 } const store=createStore(reducer,initValue) export default store 复制代码
createStorestore 可以接受一个初始的state,这里可以设置服务端同构应用的初始化props。 至此redux的相关就结束,下面写ui组件。
编写UI组件
如果不用react-redux自动生成容器组件,组件划分就要有容器组件和展示的区分,我理解的展示组件就是没有自己的state,只接受 props决定UI该如何展示,所有的逻辑都在容器组件进行,由于react-redux,我们不需要自己写容器组件
Counter
import React, { Component } from 'react'; import {increment, decrement} from '../Redux/Action' import {connect} from 'react-redux' import '../style/App.css'; const buttonMargin= { margin: "20px" } function Counter({index, Increment, Decrement, value}){ return ( <div> <button style={buttonMargin} onClick={Increment}>+</button> <button style={buttonMargin} onClick={Decrement}>-</button> <span>{index} count :{value}</span> </div> ) } function mapStateToProps(state,ownProps){ return{ value:state[ownProps.index] } } function mapDispatchToProps(dispatch, ownProps){ return{ Increment:() => { dispatch(increment(ownProps.index)) }, Decrement:() => { dispatch(decrement(ownProps.index)) } } } export default connect(mapStateToProps, mapDispatchToProps)(Counter); 复制代码
- react-redux提供方法connect()和组件,这里说下connect(),引用阮一峰大神的总结: connect方法接受两个参数:mapStateToProps和mapDispatchToProps。它们定义了 UI 组件的业务逻辑。前者负责输入逻辑,即将state映射到 UI 组件的参数(props),后者负责输出逻辑,即将用户对 UI 组件的操作映射成 Action。
- mapStateToProps:作为函数,mapStateToProps执行后应该返回一个对象,里面的每一个键值对就是一个映射。 接受两个参数state,ownProps,state 。state更新的时候,就会自动执行,重新计算 UI 组件的参数,从而触发 UI 组件的重新渲染,ownProps代表容器组件的props对象,如果容器组件的参数发生变化,也会引发 UI 组件重新渲染,例如上面个的计数;
- mapDispatchToProps是connect函数的第二个参数,用来建立 UI 组件的参数到store.dispatch方法的映射。也就是说,它定义了哪些用户的操作应该当作 Action,传给 Store。它可以是一个函数,也可以是一个对象
Panel
import React, { Component } from 'react' import Counter from './Counter.js' const style = { margin: "20px" } class Panel extends Component { render() { return ( <div style={style}> <Counter index="First" /> <Counter index="Second"/> <Counter index="Third" /> <hr/> </div> ) } } 复制代码
export default Panel
这里就是个list。
index.js(入口文件)
import React from 'react'; import ReactDOM from 'react-dom'; import './style/index.css'; import Panel from './Component/Panel'; import {Provider} from 'react-redux'; import store from './Redux/Store/store.js' import registerServiceWorker from './registerServiceWorker'; ReactDOM.render( <Provider store={store}> <Panel/> </Provider>,<pre> document.getElementById('root') ); registerServiceWorker(); 复制代码
React-Redux 提供Provider组件,可以让容器组件拿到state,避免一层层向下传,原理是context,其实也很好理解,vue有个bus。 至此一个同步的redux处理数据的demo就完成了,下面来说异步。
异步
vuex 提交的是Mutation(有点像git) 这个东西是同步, 而它有action 这里可以同步异步,但redux并没有,所以这里就有了中间件的出现,用于解决异步action,中间件有几种常用的,这里只简单写下redux-thunk。 action creator 原则是返回一个js对象,异步在这里处理,返回的是一个函数,这就需要中间件的处理。 修改这两处:
action:
export const Increment = 'increment' export const Decrement = 'decrement' export const increment = (counterIndex) => { return dispatch => { let asyncAct = { type:Increment, counterIndex } setTimeout(()=>{ //两秒钟之后再发送action dispatch(asyncAct); }, 2000) } } export const decrement = (counterIndex) => ({ type: Decrement, counterIndex }) 复制代码
store:
import {applyMiddleware, createStore} from 'redux' import thunk from 'redux-thunk' import reducer from '../Reducer' const initValue={ 'First':1, 'Second':5, 'Third':6 } const store=createStore(reducer,initValue,applyMiddleware(thunk)) //使用中间件的写法applyMiddleware,如果多个,注意里面中间件的顺序 export default store 复制代码
简单的延时2s再计数完成啦。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Learning PHP 5
David Sklar / O'Reilly / July, 2004 / $29.95
Learning PHP 5 is the ideal tutorial for graphic designers, bloggers, and other web crafters who want a thorough but non-intimidating way to understand the code that makes web sites dynamic. The book ......一起来看看 《Learning PHP 5》 这本书的介绍吧!