代码之家  ›  专栏  ›  技术社区  ›  scripton

Redux:区分减速机中的对象

  •  2
  • scripton  · 技术社区  · 9 年前

    我对Redux很陌生,据我所知,应该为每种类型的对象创建一个reducer。E、 g.对于用户交互,应该创建一个用户还原程序。 我的问题是: 如果您出于不同目的需要对象,您如何处理这些情况?

    脚本: 想象一下,有一个返回当前用户的用户reducer。该用户在整个应用程序中都是必需的,并且在每个页面上都是常规控件所必需的。

    现在,当您需要加载另一个用于不同目的的用户时会发生什么。E、 g.配置文件页面:加载用户以显示信息。

    在这种情况下,如果使用用户减速机,则会发生冲突。在Redux中处理此问题的正确方法是什么?如果必须创建不同的减速器,那么新减速器的命名约定是什么?

    1 回复  |  直到 9 年前
        1
  •  2
  •   Diego Haz    9 年前

    首先,您提到:

    加载当前用户的用户减速机

    我不知道我是否正确理解了您的意思,但如果这意味着您想要(例如,从API)获取减速机内的当前用户,那么这是一个错误的方法。

    减速器旨在 pure functions 。可以使用相同的参数多次调用它们,它们将始终返回相同的预期状态。

    这样的副作用应该由 action creators ,例如:

    操作/user.js

    export const FETCH_ME = 'FETCH_ME'
    export const FETCH_ME_SUCCESS = 'FETCH_ME_SUCCESS' 
    
    // it's using redux-thunk (withExtraArgument: api) module to make an async action creator
    export const fetchMe = () => (dispatch, getState, api) => {
      dispatch({ type: FETCH_ME })
      return api.get('/users/me').then(({ data }) => {
        dispatch({ type: FETCH_ME_SUCCESS, data })
        return data
      })
    }
    

    在您的reducer中,您可以简单地获取数据并设置新状态(请注意,如果多次使用相同的数据发送操作,状态将始终相同)。

    减速器/user.js

    import { FETCH_ME, FETCH_ME_SUCCESS } from '../actions/user'
    
    const initialState = {
      item: null,
      loading: false
    }
    
    export const userReducer = (state = initialState, action) => {
      switch (action.type) {
        case FETCH_ME:
          return {
            ...state,
            loading: true
          }
        case FETCH_ME_SUCCESS:
          return {
            ...state,
            loading: false,
            item: action.data
          }
        default:
          return state
      }
    }
    

    现在,对于您的场景:

    现在,当您需要加载另一个用于不同目的的用户时会发生什么。E、 g.配置文件页面:加载用户以显示信息。

    您只需为此编写另一个动作创建者:

    操作/user.js

    export const FETCH_ME = 'FETCH_ME'
    export const FETCH_ME_SUCCESS = 'FETCH_ME_SUCCESS' 
    export const FETCH_USER = 'FETCH_USER'
    export const FETCH_USER_SUCCESS = 'FETCH_USER_SUCCESS'
    
    export const fetchMe = () => (dispatch, getState, api) => {
      dispatch({ type: FETCH_ME })
      return api.get('/users/me').then(({ data }) => {
        dispatch({ type: FETCH_ME_SUCCESS, data })
        return data
      })
    }
    
    export const fetchUser = (id) => (dispatch, getState, api) => {
      dispatch({ type: FETCH_USER })
      return api.get(`/users/${id}`).then(({ data }) => {
        dispatch({ type: FETCH_USER_SUCCESS, data })
        return data
      })
    }
    

    然后调整减速机以管理更多机组:

    减速器/user.js

    import { combineReducers } from 'redux'
    import { FETCH_ME, FETCH_ME_SUCCESS, FETCH_USER, FETCH_USER_SUCCESS } from '../actions/user'
    
    const initialState = {
      item: null,
      loading: false
    }
    
    const meReducer = (state = initialState, action) => {
      switch (action.type) {
        case FETCH_ME:
        case FETCH_ME_SUCCESS:
          return userReducer(state, action)
        default:
          return state
      }
    }
    
    const activeReducer = (state = initialState, action) => {
      switch (action.type) {
        case FETCH_USER:
        case FETCH_USER_SUCCESS:
          return userReducer(state, action)
        default:
          return state
      }
    }
    
    const userReducer = (state = initialState, action) => {
      switch (action.type) {
        case FETCH_USER:
        case FETCH_ME:
          return {
            ...state,
            loading: true
          }
        case FETCH_USER_SUCCESS:
        case FETCH_ME_SUCCESS:
          return {
            ...state,
            loading: false,
            item: action.data
          }
        default:
          return state
      }
    }
    
    export default combineReducers({
      activeUser: activeReducer,
      me: meReducer
    })
    

    您的最终用户状态应该类似于:

    {
      me: {
        item: null,
        loading: false
      },
      active: {
        item: null,
        loading: false
      }
    }