REACT不能在reducer中进行对象赋值

时间:2017-02-08 04:46:31

标签: reactjs redux

当objectAssign将store中的状态更改为来自服务器的新数据时,我遇到了问题,结果总是得到null。

我在onEnter功能(React-Router)中调用我的动作

export function GET_SetupTabTitles() {
    store.dispatch(getSetupTabTitles());
}

这是我的行动:

import {
    TOGGLE_DRAWER_IN_APPBAR,
    GET_SETUP_TAB_TITLES,
} from '../constants/actionTypes';

import axios from 'axios';
const ROOT_URL = 'http://localhost:8000';

export function toggleDrawerInAppBar(open){
    return { type: TOGGLE_DRAWER_IN_APPBAR, openStatus: open }
}

export function getSetupTabTitles(){
    return function(dispatch){
        axios.get(`${ROOT_URL}/api/component/getSetupTabTitles`)
            .then(response => {
                dispatch({type: GET_SETUP_TAB_TITLES,
                    payload: response
                });
            });
    }
}

这是我在reducer上的初始状态:

export default {
    auth: {
        authenticated: (localStorage.getItem('laravel_user_token') !== null),
        userinfo: {
            name: null
        },
        error:""
    },
    comp: {
        openDrawerStatus: false, 
        setupTabTitles: null,
    }
};

这是我的减速机:

import {
    TOGGLE_DRAWER_IN_APPBAR,
    GET_SETUP_TAB_TITLES,
} from '../constants/actionTypes';
import initialState from './initialState';
import objectAssign from 'object-assign';

const compReducer = (state = initialState.comp, action) => {
    switch (action.type) {
        case TOGGLE_DRAWER_IN_APPBAR:
            return objectAssign({}, state, {openDrawerStatus: action.openStatus});

        case GET_SETUP_TAB_TITLES:
            console.log(action.payload.data);
            return objectAssign({}, state, {setupTabTitles: action.payload.data});

        default:
            return state;
    }
};

export default compReducer;

当我在

中执行console.log时
  

案例GET_SETUP_TAB_TITLES:

它显示:

  

数组[2] 0:0:对象1:对象

在使用JSON.stringify()时,它会显示[{"tabTitle":"Events"},{"tabTitle":"Tasks"}]

但是我的状态(setupTabTitles)根本没有改变。

我试试这个:

case GET_SETUP_TAB_TITLES:

            state.setupTabTitles.push(action.payload.data[0]);
            return state;

它有效,但我不想直接改变状态。

3 个答案:

答案 0 :(得分:1)

在代码中使用当前的ES6语法时,不需要import ojectAssign from 'object-assign';。您只需要Object.assign。此外,由于您的action.data.payload是一个数组,您需要附加到数组,您可以使用扩展运算符,如

      return { 
                ...state,
                setupTabTitles: [...state.setupTabTitles, action.payload.data]
             }

此外,您需要将componentState初始化为空数组,而不是null或undefined。将其更改为以下代码

export default {
    auth: {
        authenticated: (localStorage.getItem('laravel_user_token') !== null),
        userinfo: {
            name: null
        },
        error:""
    },
    comp: {
        openDrawerStatus: false, 
        setupTabTitles: [],
    }
};

尝试如下

const compReducer = (state = initialState.comp, action) => {
    switch (action.type) {
        case TOGGLE_DRAWER_IN_APPBAR:
            return Object.assign({}, state, {openDrawerStatus: action.openStatus});

        case GET_SETUP_TAB_TITLES:
            console.log(action.payload.data);
            return { 
                ...state,
                setupTabTitles: [...state.setupTabTitles, ...action.payload.data]
             }

        default:
            return state;
    }
};

objectAssign的语法与我使用的语法不同,您可以看到 here

var state = {
            openDrawerStatus: false, 
            setupTabTitles: [],
        }
var payload  = [{"tabTitle":"Events"},{"tabTitle":"Tasks"}]
console.log( { 
                    ...state,
                    setupTabTitles: [...state.setupTabTitles, ...payload]
                 });

答案 1 :(得分:0)

由于您已经在使用ES6,您可以使用对象扩展运算符并删除object-assign库,它将是这样的:

import {
    TOGGLE_DRAWER_IN_APPBAR,
    GET_SETUP_TAB_TITLES,
} from '../constants/actionTypes';
import initialState from './initialState';

const compReducer = (state = initialState.comp, action) => {
    switch (action.type) {
        case TOGGLE_DRAWER_IN_APPBAR:
            return { ...state, openDrawerStatus: action.openStatus };
        case GET_SETUP_TAB_TITLES:
            return { ...state, setupTabTitles: action.payload.data };
        default:
            return state;
    }
};

export default compReducer;

答案 2 :(得分:0)

在初始状态下,我会将setupTabTitlenull更改为空数组[]

setupTabTitles: [],

在你的reducer中,将数据附加到这个数组:

const compReducer = (state = initialState.comp, action) => {
    switch (action.type) {
        ...
        case GET_SETUP_TAB_TITLES:
            return { 
                ...state,
                setupTabTitles: [
                  ...state.setupTabTitles,
                  ...action.payload.data
                ]
             }
             ...
    }
};

或者,如果您不想追加,只需替换,我会这样做:

setupTabTitles: [
  ...action.payload.data
]