Ошибка инициализации редуктора при работе в стеке MERN - PullRequest
0 голосов
/ 21 апреля 2019

Я следую вместе со стековым курсом MERN от Traversy Media в разделе о сокращениях.Я получаю ошибки, связанные с инициализацией редукторов, хотя я много раз проверял свой код по отношению к коду инструктора и не могу найти разницу.

Я пытался изменить различные операторы импорта и экспорта, иногда выдает несвязанныеошибки, которые исчезают, когда я меняю его обратно.

Вот мой itemReducer.js

import uuid from "uuid";
import { GET_ITEMS, ADD_ITEM, DELETE_ITEM } from "../actions/types";

const initialState = {
  items: [
    { id: uuid(), name: "Eggs" },
    { id: uuid(), name: "Milk" },
    { id: uuid(), name: "Steak" },
    { id: uuid(), name: "Candy" }
  ]
};

export default function(state = initialState, action) {
  switch (action.type) {
    case GET_ITEMS:
      return {
        ...state
      };
  }
}

index.js

import { combineReducers } from "redux";
import itemReducer from "./itemReducer";

export default combineReducers({
  item: itemReducer
});

и ShoppingList.js

import React, { Component } from "react";
import { Container, ListGroup, ListGroupItem, Button } from "reactstrap";
import { CSSTransition, TransitionGroup } from "react-transition-group";
import uuid from "uuid";
import { connect } from "react-redux";
import { getItems } from "../actions/itemActions";
import PropTypes from "prop-types";

class ShoppingList extends Component {
  componentDidMount() {
    this.props.getIems();
  }

  render() {
    const { items } = this.props.item;
    return (
      <Container>
        <Button
          color="dark"
          style={{ marginBottom: "2rem" }}
          onClick={() => {
            const name = prompt("Enter Item");
            if (name) {
              this.setState(state => ({
                items: [...state.items, { id: uuid, name }]
              }));
            }
          }}
        >
          Add Item
        </Button>

        <ListGroup>
          <TransitionGroup className="shopping-list">
            {items.map(({ id, name }) => (
              <CSSTransition key={id} timeout={500} classNames="fade">
                <ListGroupItem>
                  <Button
                    className="remove-btn"
                    color="danger"
                    size="sm"
                    onClick={() => {
                      this.setState(state => ({
                        items: state.items.filter(item => item.id !== id)
                      }));
                    }}
                  >
                    &times;
                  </Button>
                  {name}
                </ListGroupItem>
              </CSSTransition>
            ))}
          </TransitionGroup>
        </ListGroup>
      </Container>
    );
  }
}

ShoppingList.propTypes = {
  getItems: PropTypes.func.isRequired,
  item: PropTypes.object.isRequired
};

const mapStateToProps = state => ({
  item: state.item
});

export default connect(
  mapStateToProps,
  { getItems }
)(ShoppingList);

ожидаемый результат: я ожидаю, что http://localhost:3000 загрузит список покупок с элементами, которые могут быть удалены или добавлены.

фактический результат: что я получаю, это ошибка Error: Reducer "item" returned undefined during initialization. If the state passed to the reducer is undefined, you must explicitly return the initial state. The initial state may not be undefined. If you don't want to set a value for this reducer, you can use null instead of undefined.

1 Ответ

0 голосов
/ 21 апреля 2019

Причина в том, что при создании хранилища отправляется действие INIT, чтобы каждый редуктор возвращал свое начальное состояние источник , и в вашем случае ваш редуктор не знает, как поступить с действием INIT (возвращает неопределенное значение, и поэтому вы получили ошибку)

Вы можете исправить это, добавив default корпус к вашему редуктору:

export default function(state = initialState, action) {
  switch (action.type) {
    case GET_ITEMS:
      return {
        ...state
      };
    default:
        return state
  }
}
...