Redux是一个数据状态管理插件;每个系统都需要一个管理多组件使用的公共信息功能;例如,用户登录之后客户端会存储用户信息userid和头像等,而系统的每个组件都需要用到这些信息,如收藏点评品论等。
基本使用:
1.定义计算规则,即reducer 在规则函数中,数据变化时要return一个新的值,而不能直接修改原来的值;使用了 不可变数据 的设计方式,来明确数据的变化时段,使得数据管理更清晰,复杂度更低。
function counter(state = 0,action){ 4.执行reducer,返回新的state,会更新到store tree中,-
switch(action.type){ ->到步骤1 触发由store.subscribe()注册的所有的listener
case 'INCREMENT':
return state+1
case 'DECREMENT':
return state-1
default:
return state
}
}
2.根据计算规则生成 store,根据计算规则创建store规则文件 2Redux通过全局唯一的store对象管理项目中的state
let store = createStore(counter,initialState)
3.定义数据(即state)变化之后的派发规则 1通过store注册listener,注册的listener会在store tree 每次变更后执行
store.subscribe(() => {
console.log('current state',store.getState())
})
4.触发数据变化 3 更新store tree :store调用dispatch,通过action吧变更的信息传递给reducer var action={type:...};store.dispatch(action);
store.dispatch({type:'INCREMENT'})
store.dispatch({type:'INCREMENT'})
store.dispatch({type:'DECREMENT'})
Redux是一个管理数据的工具,我们创建一个store变量来管理数据。创建store的前提是设定一个管理规则counter,默认state是0。
用store来管理数据,具体的管理形式是什么?
a.要通过一个函数来触发数据的变化,即dispatch,遵守之前的规则。
b.数据一旦发生变化,会导致什么样的后果,即执行subscribe中定义的函数
c.如何取到当前的数据,即store.getState()
Redux和React集成
1创建store,第一个参数是规则,第二个参数是初始化的数据window.STATE_FROM_SERVER(从服务器接受数据作为本地的初始化数据),第三个参数是可调起的chrome扩展程序redux-devtools
const store = createStore(rootReducer,initialState,
window.devToolsExtension ? window.devToolsExtension() : undefined 触发redux-devtools
)
b.创建规则Reducer, 现实中,数据结构复杂太多,必须分组管理。需要用state.userinfo来表示用户数据,state.nav表示导航数据,state.ad表示广告数据......
c.创建action,实际应用中,需要一些函数将它分封起来,即./app/actions中的文件,我们把每个业务操作都封装为一个函数,接收data,-->再根据reducer的规则对data进行分装,-->最后返回给dispatch来处理。
react-redux介绍:连接react和redux
react-redux是一个轻量级的封装库,其核心方法两个:Provider和connect
一 Provider:1 在原应用组件上包裹一层,使原来整个应用成为provider的子组件。
2 接受Redux的store作为props,通过context对象传递给子组件上的connect
<Provider store={store}>...</Provider>
二 connect:1包装原组件,将state和action通过props的方式传入到原组件内部。
2监听store tree 的变化,使其包装的原组件可以响应state变化
参考:http://www.cnblogs.com/hhhyaaon/p/5860159.html
fetch获取/提交数据,及开发环境下的数据Mock
fetch是一种可代替ajax获取/提交数据的技术,window.fetch。原生支持promise。
1安装:npm install whatwg-fetch --save 兼容老版本npm install es6-promise --save
2 使用:get
var result = fetch('url',{
credentials:'include', //表示跨域请求时可以带cookie
hearders:{
'Accept':'application/json,text/plain,*/*'
}});
fetch方法返回的就是一个promise对象,
result.then(res => {return res.text() }).then(text => console.log(text)})
或result.then(res => {return res.json() }).then(json => console.log(json)}}
其中res.text()和res.json()是将返回的Response数据转换成字符串 或 JSON格式
3 post
var result = fetch('url',{
methor:'POST',
credentials:'include',
headers:{
'Accept':'application/json,text/plain,*/*',
'Content-Type':'application/x-www-form-urlencoded'
},
body:'a=10&b=20'
});
数据模拟Mock
前后端分离式开发,对于后端数据使用三种模拟方式:
1 模拟静态资源数据:即按照既定的数据格式写JSON,用相关工具做接口fis3
2 模拟动态接口:自己用一个web框架,按照既定的接口和数据结构要求,模拟后端接口的功能,让项目帕奥起来。
3 转发线上接口:直接用代理获取线上的数据,适用于成熟项目。
用2 koa做接口模拟:
a 安装npm install koa koa-body koa-router --save-dev
b 在目录 ./mock下写koa代码
c 访问localhost:3000
回到Redux来
http://cn.redux.js.org/docs/introduction/ThreePrinciples.html
Redux的三个基本原则:
1 单一数据源
整个应用的state被存储在一棵object tree中,并且这个object tree只存在于唯一一个store中。
2 State是只读的
唯一改变state的方法就是触发action,action是一个用于描述已发生事件的普通对象。
3 使用纯函数开执行修改 reducers
为了描述action如何改变state tree,需要编写reducers
###Action
action是把数据从应用层传到store的有效载荷,它是store数据的唯一来源。通过store.dispatch()将action传到store.
action本质是js普通对象,其内部必须使用type来表示将要执行的动作。
import {ADD_TODO,REMOVE_TODO} from '../actionTypes'
{type:ADD_TODO,text:'Build my first Redux app'}--->实际项目中把生成的唯一ID作为数据引用标示
type表达用来处理state数据的方式。
#Action创建函数 就是生成action的方法
function addTodo(text){return {type:ADD_TODO,text}}
redux提供的combineReducers() 方法将reducer合并;var rootReducer = combineReducers({films:filmReducer,filter:filterReducer});
###Store
职责:1 维持应用的state;
2 提供store.getState()方法获取state;
3 store.dispatch(action)方法将action对象发送给reducer进行处理;可以很好的对state进行统一管理;
4 store.subscribe(listener)注册监听器,当有state数据更新时,将会触发;
5 subscribe(listener) 返回的函数注销监听器
redux提供了createStore()方法来生产Store,其中有三个可访问闭包变量的共有方法:dispatch,subscribe,getState
var actionCreators = bindActionCreators(actionCreators,store.dispatch);
===================================
Action 的异步解决方法
一 redux-thunk 中间层做数据异步转换
redux-thunk配置:redux-thunk通过redux提供的中间件applyMiddleware,绑定到store 中。
import { creactStore,applyMiddleware } from 'redux'; import thunk from 'redux-thunk' import reducers from '../reducers'; let store = creactStore( reducers, applyMiddleware(thunk) );
render(
<Provider store={store}>
...
</Provider>,
document.querySelector('#app'));
Action 使用redux-thunk
获取数据方法在异步获取数据后需要再次调用接收方法接收数据。
//接收方法
let receiveSomething = (res) => {
return {
type:RECEIVE_SOME,
res
}
}
// 获取数据方法
export let fetchSomething = (args) => {
return dispatch => {
return fetch(args).then((res) => {
return dispatch(receiveSomething(res))
})
}
}
2 将state绑定到component
使用react-redux提供的connect方法将组件和所需数据绑定。
let mapStateToProps = (state) => {
....}
const FilterLink = connect(mapStateToProps,mapDispatchToProps)(ComponentA)
export default FilterLink
==============================
import { PropTypes } from 'react'
import { combineReducers } from 'redux' 合并子reducer const todoApp = combineReducer({todos,filter})
import { connect } from 'react-redux' 将state绑定到component
import { creactStore } from 'redux' const store = creactStore(reducer)
import { Provider } from 'react-redux' <Provider store={store}>