Redux 优化的一些思考

React干货 admin 暂无评论

Redux 的书写分离

从 Redux 官方示例开始,我们就采用了 actions 和 reducers 分开文件夹来维护的思路。

但是在实际业务中,大部分场景下一个 action 触发的 reducer 是在一个子 reducer 下。

这里其实引入了 combineReducers 工具来分离大型的 store 数据。

然而饱受诟病的正是一个用户操作开发起来要写多个文件,component, action, reducer, api… 非常不方便,所以我们考虑将 action 和 reducer 合并在一个文件中书写。

于是我们移除 actions 和 reducers 文件夹,新建一个 redux 目录,里面放业务文件,如:

// newsList.js
import getNewsAPI from '../api/getNews';

import createReducer from '../lib/createReducer';
import processErrors from '../lib/processErrors';

import * as actionTypes from '../config/actionTypes';

const defaultState = {
   loading: false,
   list: [],
};

export default createReducer(defaultState, {
   [actionTypes.GET_MORE_NEWS]: (state, action) => {
       switch (action.status) {
           case 'loading':
               return { ...state, loading: true };
           case 'success':
               return { ...state, loading: false, list: [ ...state.list, ...action.payload ] };
           case 'error':
               return { ...state, loading: false };
       }
       return state;
   },
   [actionTypes.CLEAR_NEWS_LIST]: (state, action) => {
       return { ...state, list: [] };
   },
});

export const getMoreNews = () => {
   return async(dispatch) => {
       try {
           dispatch({
               type: actionTypes.GET_MORE_NEWS,
               status: 'loading',
           });
           const list = await getNewsAPI();
           dispatch({
               type: actionTypes.GET_MORE_NEWS,
               status: 'success',
               payload: list,
           });
       } catch (ex) {
           dispatch({
               type: actionTypes.GET_MORE_NEWS,
               status: 'error',
           });
           processErrors(ex);
       }
   };
};

export const clearNewsList = () => {
   return {
       type: types.CLEAR_NEWS_LIST,
   };
};

这里我们利用 export default 和 export cont 来区分 reducer 和 action,外部使用 reducer 时 import newsListReducers from ‘./newsList’; 得到的 newsListReducers 是一个方法,并不包含 getMoreNews 和 clearNewsList 两个方法,比较纯净。

同时使用 action 时通过 import { getMoreNews, clearNewsList } from ‘../redux/newsList’; 拿到 function。

action 和 reducer 的对应关系

action 和 reducer 并不一定是一一对应的,部分场景下一个 action 可以触发多个 reducer 的处理。

因此 actionTypes 定义在 config 文件中作为常量管理可以方便在多个文件中使用。

redux-thunk 的 dispatch 并不一定是必须的

在上面的例子中,我们试用了 redux-thunk 中间件来支持异步 action,并且推迟 action 的执行。有些人会以为这里写同步 action 的时候也需要嵌套一层 dispatch

export const clearNewsList = () => {
   return (dispatch) => {
       dispatch({
           type: types.CLEAR_NEWS_LIST,
       });
   };
};

这种写法有点多余,我们可以直接 return action 对象。

export const clearNewsList = () => {
   return {
       type: types.CLEAR_NEWS_LIST,
   };
};

Redux 的性能问题

很多人都认为 react 组件的 props 和 state 没有变更的时候不会执行组件的 render 方法,但是这个看法是不正确的。默认的,只要父组件 render 方法执行了,子组件的 render 是会执行的。

除非我们在子组件上实现了 shouldComponentUpdate 方法,这个可以避免作组件多余的 render 计算。react-redux 提供的 connect 正是实现了这个方法,因此 connect 用得越多,项目性能越好。


转载请注明:React教程中文网 - 打造国内领先的react学习网站-react教程,react学习,react培训,react开 » Redux 优化的一些思考

喜欢 ()or分享