基本概念
View:视图层,接收用户输入、监听状态改变
Action:视图层发出的消息
Dispatcher:接收Actions,执行回调函数
Store:存放应用的状态,一旦状态改变,通知View更新页面
特点:数据单向流动
Action -> Dispatcher -> Store -> View -> Action
行为:
View
,View 层接收用户的输入Dispatcher
提供的 dispatch
方法,发送一个 Action
对象,包括 type 类型 和 其他参数register
方法了里面登记了各种 Action
的回调函数,当 dispatch
方法被调用的时候,就会执行这个回调函数,接收 Action ,根据 type
通知 Store
进行相应的更新change
事件ComponentDidMount
的时候监听 change 事件,当 change 触发之后,更新组件自身的 stateComponentWillUnmount
的时候移除监听事件。和看阮大大的demo一起理解上述文字更清晰:http://www.ruanyifeng.com/blog/2016/01/flux.html
redux的思想:就是把所有的状态都放在一个统一个store中,当你想要改变状态的时候就要触发一个action,action编写reducer去改变state,整个state的改变是在reducer中发生的,不会有任何的副作用。
把根级的 reducer 拆成多个小的 reducers
整个应用的 state 存储在一棵对象树中,并且这个对象树存在于唯一的 store 中。
唯一改变 state 的方法就是触发 action,强制使用 action 来描述所有变化可以清晰的知道应用中到底发生了什么。
为了描述 action 是如何更改 state 的,需要编写 reducer,随着应用变大,你可以把它拆成多个小的 reducers
纯函数:接收一个 state 和 action,并返回新的 state 的函数
import { combineReducers, createStore } from "redux";
let reducer = combineReducers({ visibilityFilter, todos });
let store = createStore(reducer);
store 保存整个应用的state,并且还提供一些方法,比如:
action 是一个纯 javascript 对象,包括 type,payload 属性,type 表示 action 的类型,指出应该触发reducer中的哪个函数来修改state
reducer 是一个纯函数,以 先前的 state 和 一个 action 为参数,返回一个新的 state 的函数。
Redux Thunk 是一个允许你编写返回一个函数而不是一个 action 的 actions creators 的中间件。
如果满足某个条件,Thunk 可以用来延迟 action 的派发、异步处理 action的派发。
定义 dva 中的 model:
export default {
namespace: "user", // 命名模块名称
state: {
// model中的状态
profile: null
},
subscriptions: {
//组件的所有生命周期都可以在这里找到对应的api去调用
setup({ dispatch }) {
dispatch({
type: "initUserInfo"
});
}
},
effects: {
// 处理所有的网络请求
*initUserInfo({ payload }, { call, put, select }) {
let userState = yield select(state => state.user.profile);
let user = yield call(userService.fetUserInfo);
if (!userState) {
yield put({
type: "setUserProfileReducer",
profile: user
});
}
}
},
reducers: {
// 改变state
setUserProfileReducer(state, { profile }) {
return {
...state,
profile
};
}
}
};
dispatch({ type: ‘fetch’}); //如果是当前 model 可以直接写方法名如果是别的 model 的那你需要前面加上 model 名字 { type: ‘OtherModel/fetch’}
在组件中使用 model:
import { connect } from "dva";
// dispatch 用来发起一个请求
const IndexPage = ({ dispatch, state }) => {
// 在组件的事件中触发
function(){
dispatch({
type : "modelName/name"
payload : ""
})
}
return <Index />;
};
// 使用dva的connect方法连接组件和model
export default connect(({ state }) => ({
state
}))(IndexPage);
import { connect } from "dva";
class AppointmentPage extends React.Component {
handleClick(){
// dispatch方法会在this.props里面。
this.props.dispatch({
type: 'modelName/name'
})
}
render(){
return (...)
}
}
export default connect(({ modelName }) => ({
modelName
}))(Component);
学习 dva 的一些体悟 https://juejin.im/post/59c5b29b5188257e8c55000b
编写 store:
import { observable, action } from "mobx";
class MyStore {
@observable list = [];
@computed
get total() {
return this.price * this.amount;
}
@action
async fetch({ payload, resolve, reject }) {
try {
let res = await services.fetch(payload);
if (res) {
this.list = res.data.data;
resolve && resolve();
}
} catch (e) {
reject && reject();
console.error(e);
}
}
}
const myStore = new MyStore();
export default myStore;
在组件中使用 mobx:
import { inject, observer } from 'mobx-react';
@inject('MyStore')
@observer
class Example extends React.Component{
componentDidMount() {
this.props.MyStore.fetch()
}
}
export defaultExample;
store 将存在于组件的 props 中。更多 api 请移步: http://cn.mobx.js.org/