update 2021
明确目的,我们需要一个存储数据的地方,并且这个数据可以变更,所以有了reducer
const initialCourseState = {
courseList: [],
courseTotal: 0,
}
export default function courseReducer(state = initialCourseState, action) {
switch (action.type) {
case ActionTypes.COURSE_GET_COURSE_LIST:
const { list, total } = action.payload;
return {...state, courseList: list, courseTotal: total};
default:
return state
}
}然后,我们发现一个reducer不满足需求,不利于模块拆分,所以要合并reducer
import courseStore from './courseStore';
import teacherStore from './teacherStore';
const rootReducer = combineReducers({
courses: courseStore,
teachers: teacherStore
});等我们想去执行数据加载时,忽然发现reducer不支持,所以有了action和redux-thunk中间件
const composedEnhancer = composeWithDevTools(applyMiddleware(thunkMiddleware));
const store = createStore(rootReducer, composedEnhancer);
...
export function getCourseList(params) {
return async function getCourseList(dispatch, getState) {
dispatch({
type: ActionTypes.COURSE_GET_COURSE_LIST,
payload: {
list: [12,312,31,Math.random()],
total: 0
}
})
}
}最后就可以直接调用action
import store from './store';
import { getCourseList } from './store/courseStore';
...
store.dispatch(getCourseList);别忘了如果在React中使用和纯JavaScript还是有区别的
import { useDispatch, useSelector } from 'react-redux';
...
const { courseList, courseTotal } = useSelector(state=>state.courses)
...
const dispatch = useDispatch();
dispatch(getCourseList({ limit: 10, offset: 0 }));update 2019-04-06redux 核心概念包括一个数据源,可预测无副作用的变更数据函数,传递消息的动作函数(action更好的描述为类似mvc中的逻辑层)。 首先调用 action 触发动作, action 通知 reducer 做变更,数据变更后 react 触发对比界面更新。
理解了核心概念基本就没问题了,其他的就是重复的样板代码工作,当然可能还会有一些困扰,比如有大量弹窗的页面如何处理弹窗的状态。目前在用的 dva 框架也不错,逻辑使用上来说更加清晰,但是比较不爽的是用了 yield 而没用 async
created 2017
intro
Store
数据
const store = createStore(reducer, 0);Reducers
接收事件,进行处理
const reducer = function(state, action){
if(action==='INC'){
return state + 1;
}
return state;
}Dispatch
分发事件
store.dispatch({ type:'INC', payload: 123 })
// 更多的时候会封装成 action 再分发
export function inc(num) {
return { type: 'INC', num}
}Action
因为 Reducer 是纯函数, 所以需要其它的东西来做脏活累活
React Redux
你首先要明白, 很多库已经不是框架独占的了
redux 可以用在 angular, vue, 甚至于纯 js 中
react-redux 提供了两个东西: Provider 组件和 connect 函数
Provider
Provider 把我们的程序包起来就可以了, 只有在此组件之前的控件可以订阅 store
<Provider store={store}>
<App />
</Provider>connect
connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])connect 高阶函数可以帮我们订阅 store 注入到当前组件中
@connect(({ apps: { targetApp } }) => {
return { targetApp }
}, {
fetchAppAction
})
export default class appDetail extends Component {
// ...
}