随笔

React-Redux

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不支持,所以有了actionredux-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-06
redux 核心概念包括一个数据源,可预测无副作用的变更数据函数,传递消息的动作函数(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 {
    // ...
}

Resources

https://cn.redux.js.org/docs/react-redux/

本文链接:https://note.lilonghe.net//post/react-redux.html

-- EOF --