初始默认状态未显示,显示为空

时间:2019-09-16 00:48:58

标签: javascript reactjs redux react-redux

这是来自Dave Ceddia的Redux课程的一个教程作业,我试图显示包含对象数组的初始状态,但是它只是返回未定义的内容而不显示任何内容。我是React的新手,在获取1)我的按钮以显示状态和2)默认状态为最初出现时遇到了麻烦。

我试图将组件Buttons作为类和常量。 我也尝试在我的减速器的initialReducer中声明我的default: return state;。我还对调度操作尝试了不同的语法,但减速器似乎没有任何作用。

index.js

import React, { Fragment } from "react";
import ReactDOM from "react-dom";
import { getAllItems, addEventToBeginning, addEventToEnd } from "./actions";
import { connect, Provider } from "react-redux";
import { store } from "./reducers";

const Buttons = ({
  state,
  getAllItems,
  addEventToBeginning,
  addEventToEnd
}) => (
  <React.Fragment>
    <ul>{state ? state.actions.map(item => <li>{item}</li>) : []}</ul>
    <button onClick={getAllItems}> Display items </button>
    <button onClick={addEventToBeginning}> addEventToBeginning </button>
    <button onClick={addEventToEnd}> addEventToEnd </button>
  </React.Fragment>
);

const mapDispatchToProps = { getAllItems, addEventToBeginning, addEventToEnd };

const mapStateToProps = state => ({
  actions: state.actions,
  sum: state.sum
});

connect(
  mapStateToProps,
  mapDispatchToProps
)(Buttons);

reducers.js

const initialState = {
  actions: [
    { id: 0, type: "SALE", value: 3.99 },
    { id: 1, type: "REFUND", value: -1.99 },
    { id: 2, type: "SALE", value: 17.49 }
  ],
  sum: 0
};
const newUnit = { id: Math.random * 10, type: "SALE", value: Math.random * 25 };

function eventReducer(state = initialState, action) {
  switch (action.type) {
    case ADD_EVENT_TO_BEGINNING:
      const copy = { ...state };
      copy.actions.unshift(newUnit);
      return copy;
    case ADD_EVENT_TO_END:
      const copy2 = { ...state };
      copy2.actions.unshift(newUnit);
      return copy2;

切出干净

    case GET_ITEMS:
      return {
        ...state,
        actions: state.actions,
        sum: state.sum
      };
    default:
      return state;
  }
}

export const store = createStore(eventReducer);

actions.js示例(它们都遵循相同的格式)

export const ADD_EVENT_TO_BEGINNING = "ADD_EVENT_TO_BEGINNING";

export function addEventToBeginning() {
  return dispatch => {
    dispatch({
      type: ADD_EVENT_TO_BEGINNING
    });
  };
}

更新:

谢谢@ ravibagul91和@Yurui_Zhang,我将除getAllItems之外的所有内容都剪掉了,并将状态更改为:

const initialState = {
  itemsById: [
    { id: 0, type: "SALE", value: 3.99 },
    { id: 1, type: "REFUND", value: -1.99 },
    { id: 2, type: "SALE", value: 17.49 }
  ]
};
class Form extends React.Component {
  render() {
    return (
      <div>
        {this.props.itemsById
          ? this.props.itemsById.map(item => (
              <li>
                {item.id} {item.type} {item.value}
              </li>
            ))
          : []}
        <button onClick={this.getAllItems}> Display items </button>
      </div>
    );
  }
}

const mapDispatchToProps = { getAllItems };

function mapStateToProps(state) {
  return {
    itemsById: state.itemsById
  };
}
export function getAllItems() {
  return dispatch => ({
    type: "GET_ITEMS"
  });
}

2 个答案:

答案 0 :(得分:0)

您的代码有多个问题:

const mapStateToProps = state => ({
  actions: state.actions,
  sum: state.sum
});

这里您已将redux状态字段映射到道具actionssum-您的组件将不会收到state道具,而是它将收到actions和{{ 1}}。

所以您的组件确实应该是:

sum

您的const Button = ({ actions, sum, }) => ( <> <ul>{actions && actions.map(item => <li>{item}</li>)}</ul> </> ); 函数未正确定义。应该是这样的:

mapDispatchToProps

您的reducer似乎也没有正确定义,但是您应该尝试解决我首先提到的问题:)

在学习react / redux时,不要一劳永逸。我建议您回顾一下基础知识(数据流如何工作,如何将状态从redux存储映射到您的组件,什么是动作创建者等)。

答案 1 :(得分:0)

在破坏道具时,

// ideally you don't want the function names in your component to be the same as the ones you imported so I'm renaming it here: 
import { getAllItems as getAllItemsAction } from "./actions";

// you need to actually `dispatch` the action
const mapDispatchToProps = (dispatch) => ({
  getAllItems: () => dispatch(getAllItemsAction()),
});

您无权访问const Buttons = ({ state, getAllItems, addEventToBeginning, addEventToEnd }) => ( ... ,而是需要直接使用stateactions

sum

您的mapDispatchToProps应该是

const Buttons = ({
  actions,   // get the actions directly
  sum,      // get the sum directly 
  getAllItems,
  addEventToBeginning,
  addEventToEnd
}) => (
  <React.Fragment>
    //You cannot print object directly, need to print some values like item.type / item.value
    <ul>{actions && actions.length && actions.map(item => <li>{item.type} {item.value}</li>)}</ul>   
    <button onClick={getAllItems}> Display items </button>
    <button onClick={addEventToBeginning}> addEventToBeginning </button>
    <button onClick={addEventToEnd}> addEventToEnd </button>
  </React.Fragment>
);

或者您可以使用const mapDispatchToProps = dispatch => { return { // dispatching actions returned by action creators getAllItems : () => dispatch(getAllItems()), addEventToBeginning : () => dispatch(addEventToBeginning()), addEventToEnd : () => dispatch(addEventToEnd()) } }

bindActionCreators

import { bindActionCreators } from 'redux' function mapDispatchToProps(dispatch) { return { dispatch, ...bindActionCreators({ getAllItems, addEventToBeginning, addEventToEnd }, dispatch) } } 中,reducer应该将元素添加到数组的末尾,但是您将使用ADD_EVENT_TO_END在开头重新添加元素。您应该使用unshift,它将在数组的末尾添加元素,

push

您的case ADD_EVENT_TO_END: const copy2 = { ...state }; copy2.actions.push(newUnit); //Add element at the end return copy2; 也应该如此简单

GET_ITEMS