如何更好地处理简单的React-Redux Reducer

时间:2018-03-11 21:44:48

标签: reactjs redux react-redux

我一直在读关于从我的reducer(React-redux)返回的规范化状态,我想我明白,如果我不传播(...)状态返回,我的React应用程序将无法识别状态更改已发生且我的UI将不会更新。

也就是说,如果我返回一些东西:

data: action.payload.data     // where this is an array

而不是我在下面的内容

...action.payload.data

我的用户界面没有更新(没有调用render())。

假设这是正确的(我的测试似乎显示),那么我对如何返回错误条件感到困惑。我在下面所做的是返回isLoading并将isErrored作为属性来代替单个数组属性。

这感觉很难看。就像我使用我的回归意味着成功的一件事和错误的另一件事。

建议更好的方法吗?我错过了什么?

export function sessionAttendee(state = {}, action) {                    
    switch (action.type) {
        case SESSIONATTENDEE_LOAD: {
            return Object.assign({}, state, {
                isLoading: true,
                hasErrored: false
            });
        }

        case SESSIONATTENDEE_LOAD_SUCCESS: {
            return Object.assign({}, state, {
                ...action.payload.data
            });
        }

        case SESSIONATTENDEE_LOAD_FAIL: {
            console.log("SESSIONATTENDEE_LOAD_FAIL");
            return Object.assign({}, state, {
                isLoading: false,
                hasErrored: true,
                errorMessage: action.error.message
            });
        }

1 个答案:

答案 0 :(得分:1)

Object.assign返回一个新对象。这将确保您不会改变以前的状态。 this GitHub issue中有很多充分理由说明为什么要避免改变你的状态。

关于你的陈述“这感觉很难看。就像我使用我的回报意味着成功的一件事和错误的另一件事”我会说你实际上并没有使用你的回报做多件事。它们总是返回该reducer的状态对象。 switch语句中的所有不同之处在于您正在更新该对象的属性。

FWIW,我注意到你正在Object.assign范围内传播,这可能是不必要的。这是我如何重写你的减速器,这样对我来说更有意义......

const initialState = {
    isLoading: false,
    hasErrored: false,
    errorMessage: null
    data: [],
}

export function sessionAttendee(state = initialState, action) {                    
    switch (action.type) {
        case SESSIONATTENDEE_LOAD: {
            return {
                ...state,
                isLoading: true,
                hasErrored: false
            }
        }

        case SESSIONATTENDEE_LOAD_SUCCESS: {
            return {
                ...state,
                data: action.payload.data
            }
        }

        case SESSIONATTENDEE_LOAD_FAIL: {
            return {
                ...state,
                isLoading: false,
                hasErrored: true,
                errorMessage: action.error.message
            }
        }

    default: 
        return state;
    }
}
  1. 定义了initialState因为这使得阅读时更容易理解。不是要求,但我发现它有帮助。
  2. Object.asssign切换到使用ES6点差运算符。
  3. 确保您的action.payload.data密钥实际上已分配给状态对象上的属性,而不仅仅是将其清除。