Невозможно обновить объект в Redux без перезаписи или потери других элементов в состоянии - PullRequest
0 голосов
/ 29 октября 2018

Краткий обзор ..

Мое состояние выглядит так:

isAuthenticated: true

user: {
  avatar: 'avatar.jpg'
  name: 'John Doe'
  username: 'johndoe'
  id: '6dHjStye45fds885'        
}

И я пытаюсь обновить только свойство avatar с помощью Redux в редукторе, но все, что я пробовал, работает, как ожидалось. Должно быть, я делаю это неправильно, но просто не знаю что Я прочитал столько, сколько я могу найти на предмете, и ничто, кажется, не работает правильно.

Если я сделаю это:

return {
   ...state,
     user: {
       ...state.user,
       avatar: action.payload
     }
};

Полностью стирает isAuthenticated и заменяет объект user просто аватаром, уничтожая все остальное, что было в предыдущем состоянии. Я предполагаю, что я уничтожаю операторы спреда с помощью avatar: action.payload?

А если сделать это:

return {
  ...state,
    ...state.user,
    avatar: action.payload
};

Он также стирает isAuthenticated, но на этот раз все пользовательские данные (включая новые avatar) помещаются на верхний уровень состояния (больше не в объекте).

Может кто-нибудь показать мне, где я иду не так?

РЕДАКТИРОВАТЬ добавление соответствующих файлов

authReducer.js (усеченное удаление ненужного кода)

import isEmpty from '../../functions/isEmpty';
import { SET_CURRENT_USER, SET_AVATAR } from '../actionTypes';

const initialState = {
  isAuthenticated: false,
  user: {}
};

export default function(state = initialState, action) {
  switch (action.type) {
    case SET_CURRENT_USER:
      return {
        ...state,
        isAuthenticated: !isEmpty(action.payload),
        user: action.payload
    };
    case SET_AVATAR:
      return {
        ...state,
          user: {
            ...state,
            avatar: action.payload
          }
      };
    default:
      return state;
  }
}

rootReducer.js

import { combineReducers } from 'redux';
import authReducer from './reducers/authReducer';
import errorReducer from './reducers/errorReducer';

export default combineReducers({
  auth: authReducer,
  errors: errorReducer
});

store.js

import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './rootReducer';

const initialState = {};

const middleware = [thunk];

const store = createStore(
  rootReducer,
  initialState,
  compose(
    applyMiddleware(...middleware),
    window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
  )
);

export default store;

Ответы [ 3 ]

0 голосов
/ 29 октября 2018

Похоже, что в store.js вы передаете начальное состояние как пустой объект. Это может быть причиной того, что все продолжает стираться, когда вы используете оператор распространения.

Попробуйте импортировать состояние по умолчанию из того места, где вы его объявили, и создайте объект со всеми состояниями по умолчанию для использования в createStore.

import { initialState as authInitialState } from './authReducer.js'
import { initialState as errorInitialState } from './errorRerducer.js'

const initialState = { ...authInitialState, ...errorInitialState };
0 голосов
/ 29 октября 2018

изменить код в authReducer.js файле,

из этого

case SET_AVATAR:
  return {
    ...state,
      user: {
        ...state,
        avatar: action.payload
      }
  };

к этому

case SET_AVATAR:
  return {
    ...state,
      user: {
        ...state.user,
        avatar: action.payload
      }
  };

или это

case SET_AVATAR:
  return {
    isAuthenticated: state.isAuthenticated,
    user: {
      ...state.user,
      avatar: action.payload
    },
  };
0 голосов
/ 29 октября 2018

Вам необходимо вернуть новый объект в authReducer.js

var newUserObject = Object.assign({}, state.user, {
     avatar: action.payload.avatar   // or some other fields
})

return Object.assign({}, state, {user: newUserObject})
...