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 {
// ...
}