Вложенный Redux Reducer возвращает нулевое исходное состояние - PullRequest
0 голосов
/ 27 апреля 2018

У меня есть вложенный редуктор для задач. Я использую библиотеку " reselect " для вложенных объектов. Ниже вы можете найти редуктор и селектор ADD_TODO, но когда я вызываю редуктор ADD_TODO; это делает состояние таким, как это;

{
  0: null,
  1: null,
}

Добавить Todo Reducer

import { makeSelectTodos } from 'containers/HomePage/selectors';

const initialState = fromJS({
  todos: [],
  visibilityFilter: 'SHOW_ALL',
});

const todo = (state, action) => {
  switch (action.type) {
    case 'ADD_TODO':
      return {
        id: action.id,
        text: action.text,
        completed: false,
      };
    default:
      return state;
  }
};

function homeReducer(state = initialState, action) {
  switch (action.type) {
    case ADD_TODO:
      return [
        makeSelectTodos(),
        todo(undefined, action),
      ];
    default:
      return state;
  }
}

Selector.js

import { createSelector } from 'reselect';

const selectHome = (state) => state.get('home');

const makeSelectTodos = () => createSelector(
  selectHome,
  (homeState) => homeState.get('todos')
);

export {
  selectHome,
  makeSelectTodos,
};

Ответы [ 2 ]

0 голосов
/ 30 апреля 2018

Проблема в mapStateToProps из-за отсутствия использования неизменяемого, поэтому я получаю другую структуру данных. С помощью неизменного «getIn» я нашел решение.

0 голосов
/ 27 апреля 2018

Похоже, вы хотите вернуть все задачи в homeReducer с типом действия 'ADD_TODO'. Это не совсем верно. Ваш компонент со списком задач должен подумать об этом, и он может получить все задачи через селектор selectAllTodos.

Вы также не указали состояние для функции makeSelectTodos. Как я вижу, ваш селектор возвращает функцию, которая возвращает функцию createSelector. Здесь есть ошибка. Вам нужно написать что-то вроде этого:

const selectHome = state => state.get('home');
const selectAllTodos = createSelector(
    selectHome,
    homeState => homeState.get('todos')
);

В действии создатели-селекторы могут использоваться следующим образом:

// action creators:

const addTodoAction = todo => ({
    type: 'ADD_TODO',
    payload: todo
});

const addTodo = todo => (dispatch, getState) => {
    // here you able to use your selectors like:
    // const todos = selectAllTodos(getState());

    return dispatch(addTodoAction(todo));
};

Упростите свою логику редуктора настолько, насколько вы можете:

const todosReducer = (state = [], action) => {
    if (action.type === 'ADD_TODO') {
        return {
            id: action.payload.id,
            text: action.payload.text,
            completed: false
        };
    }

    return state;
};

const visibilityFilterReducer = (state = 'SHOW_ALL', action) => {
    // your visibility filter reducer logic
};

export default combineReducers({
    todos: todosReducer,
    visibilityFilter: visibilityFilterReducer
});

Удачи! :)

...