课程介绍
- Flux/reFlux/Redux
简单/单一状态树
react 和 redux 数据流的关系
JS、CSS、HTML
JSX
webpack 构建
数据流
- MVC 状态复杂之后,action会触发事件 并且不可预测
- flux: state Tree will send data to view,but view can't send data to state-tree.
- Redux : state 是包含在store中的
安装
npm install react
npm install redux react-redux --save
快速开始(速成版本):
核心概念
action
: React行为/变化的描述 是一个对象dispatch
: 派发用户行为的一个方法store
的一个属性reducer
: 接收action
,并进行简单的拼接,其内部是纯函数
(到底什么是纯函数请移步百度 : 传送门 、 速达传送门)store
:存储数据的地方
Get start:
step1 : 安装依赖
npm install redux react-redux --save
step2 : 创建一个 AppProvider.js 并导出AppProvider组件 : AppProvider 作为APP的入口组件
export default AppProvider;
step3 : AppProvider.js 中导入头文件
import { Provider } from 'react-redux'; import { createStore } from 'redux';
step4 : 准备AppProvider的包装数据:
创建全局的store用于存储状态,并绑定reducer
const store = createStore(AppReducer)
包装APPProvider:
const AppProvider = () => { return ( //KR-1 包裹一层Provider 之后进入被包裹控件内部 进行关联处理 <Provider store={store}> <RootStack /> </Provider> ) };
index.ios.js 文件中注册下 AppProvider对象
AppRegistry.registerComponent('XinLiFM', () => AppProvider);
step5 : 数据绑定 找到打算有 数据流传递 的对象 AppFind
导入头文件:
import { connect } from 'react-redux';
绑定数据:
//用来获取更新后的数据 监听数据更新 const mapStateToProps = (state,ownProps) => { console.log(state); return { testShow: state.find.testShow, } } //用来派发消息 const mapDispatchToProps = (dispatch,ownProps) => ({ changeTabBar: (...args) => dispatch(showTabBar(...args)), }); //用来进行数据流 和 控件的绑定关系 export default connect(mapStateToProps,mapDispatchToProps)(AppFind)
派发消息:
this.props.changeTabBar(!this.props.testShow)
消息处理:step4 中绑定的reducer文件中:
//1.导入头文件 import { combineReducers } from 'redux'; //2.创建初始化状态 const initialState = { testShow: true}; //3.逻辑处理 const find = (state = initialState, action) => { switch (action.type) { case 'findshowTabBar':{ return Object.assign({}, state, { testShow: action.testShow }) } default: return state; } } //4.组合所有的逻辑块 const AppReducer = combineReducers({ find, //如果业务繁多这里可能还有别的模块 }); //5.导出 export default AppReducer;
获取更改状态值:
//因为上一步的绑定数据 就是将state的状态值 绑定到AppFind的props上, //所以取值的时候直接从this。props中取即可 var {testShow,isShowTab,showTabBar} = this.props; <Text style={{fontSize:17,color:testShow?"red":'rgb(39, 249, 110)'}}> {testShow?"我要显示某个东西":"我要隐藏某个东西"} </Text>
总结:
其实这里最重要的就三步:1. 包装 2、数据绑定 3、数据处理
基础
1. action
信息的携带者。
派发消息的几种方式:
- 直接发送:
dispatch({type:'action_name',index:2});
const myAction = {
type:'action_name',
index: 1,
}
dispatch(myAction);
- 通过Action的创建函数发送:
//我们可以把所有的Action封装到一个固定文件 就想CSS文件那样 头文件导入的方式 去引用
const actionFunc = (text) => {
return {
type: 'action_name',
index: 2,
}
}
//派发消息时候 直接引用创建函数的返回结果即可
dispatch(actionFunc('test'));
- 绑定的Action创建函数
//基本action创建函数
const actionFunc = (text) => {
return {
type: 'action_name',
index: 2,
}
}
//绑定派发方法
const boundAction = (test) => {
dispatch(actionFunc(test));
}
//使用绑定好的派发函数
boundAction('test');
2. reducer
纯函数;
方法结构
(previouseState,action) => newState
给一个旧的state 和一个action 生成 一个新的 state。
基本方法
const initialState = { testShow: true}; const home = (state = initialState, action) => { switch (action.type) { case 'homeshowTabBar':{ console.log("homeshowTabBar:%s",action.testShow); //合并状态值 return Object.assign({}, state, { testShow: action.testShow; }) } default: return state; } }
合并state的时候下面的方法也是能达到相同效果的
{...state, ...newState}
拆分合并reducer
const home = (state = initialState, action) => { switch (action.type) { case 'homeshowTabBar':{ console.log("homeshowTabBar:%s",action.testShow); return Object.assign({}, state, { testShow: action.testShow }) } default: return state; } } const find = (state = initialState, action) => { switch (action.type) { case 'findshowTabBar':{ return Object.assign({}, state, { testShow: action.testShow }) } default: return state; } } //合并 const AppReducer = combineReducers({ nav, home, find, }); export default AppReducer
注意上面的写法和下面完全等价!!!:
const AppReducer = (state={}, action) => { return { home: home(state.home,action), find: find(sate.find,action), } }
减少代码量 自动定义 reducerCreator
export const testCreator = myCreatorForReducer([], { [ActionTypes.ADD_TODO](state, action) { let text = action.text.trim(); return [...state, text]; } }) const myCreatorForReducer = (initialState,handles) => { return (state=initialState,action) => { return handles[action.type](state,action); }else { return state; } }
设置不同的Key、调用不同的方法:
const reducer = combineReducers({ a: doSomethingWithA, b: processB, c: c }) function reducer(state = {}, action) { return { a: doSomethingWithA(state.a, action), b: processB(state.b, action), c: c(state.c, action) } }
3. store
- 维持应用的
state
; - 提供
getState()
方法获取state
; - 提供
dispatch(action)
方法更新state
; - 通过
subscribe(listener)
注册监听器; - 通过
subscribe(listener)
返回的函数注销监听器。
import { createStore } from 'redux'
import todoApp from './reducers'
let store = createStore(todoApp)
后续会更新的................