为什么在react-redux中的action-creator函数中没有定义一个动作?

时间:2017-12-04 22:25:52

标签: reactjs react-redux

在尝试使用react-redux创建一个简单的约会应用程序时,我得到一个错误,其中未定义操作中的一个项目(姓氏)。其他两个项目(firstname和id)已正确定义。为什么在定义其他操作项时未定义此操作项?我觉得我错过了react-redux中的一个关键概念。你能解释为什么没有定义动作以及如何纠正它? 行动的创作者:

import { ADD_BOOKING, DELETE_BOOKING } from "../constants";

const uid = () => Math.random().toString(34)

export const addBooking=function (firstname,lastname){

    const action={
        type:ADD_BOOKING,
        payload:{firstname,     
                lastname,
                id:uid()

        }
    }
console.log('action in addBooking',action);
return action;
}

export const deleteBooking = (id) => {
    const action = {
        type: DELETE_BOOKING,
        id: id
    };
    console.log("deleting in actions", action);
    return action;
};

减速器:

import { ADD_BOOKING, DELETE_BOOKING} from "../constants";


const booking = action => {
    return {
        firstname: action.payload.firstname,
        lastname: action.payload.lastname,
        id: action.payload.id
    };
};

const removeById = (state = [], id) => {
    //filter those not clicked
    const bookings = state.filter(booking => booking.id !==id);
    console.log("new reduced bookings", bookings);
    return bookings;
};

const bookings = (state = [], action) => {
    let bookings = null;
    switch (action.type) {
        case ADD_BOOKING:
            bookings = [...state, booking(action)];
            console.log("bookings as state", bookings);
            return bookings;
        case DELETE_BOOKING:
            bookings = removeById(state, action.id);
            return bookings;

        default:
            return state;
    }
};
export {bookings};

控制台日志: console log:

组件(App.jsx):

import React, { Component } from "react";
import "./App.css";
import "bootstrap/dist/css/bootstrap.min.css";
import { addBooking, deleteBooking } from "../actions";
import { Header } from "./NavigationBar";
import { connect } from "react-redux";

class App extends Component {
  //Initialize the Component
  constructor(props) {
    super(props);
    this.state = {
      firstname: "",
      lastname: "",
      duedate: ""
    };
  }
  //add Booking
  addBooking() {
    this.props.addBooking(this.state.firstname);
    this.props.addBooking(this.state.lastname);

  }

  //delete Booking
  deleteBooking(id) {
    this.props.deleteBooking(id);
  }
  //render the bookings
  renderBookings() {
    //access our bookings

   const {bookings} = this.props;

    return (
      <ul className="list-group col-sm-4">
        { bookings.map(booking => {
            return (<li key={ booking.id } className="list-group item">
                      <div className="list-item">
                        { booking.firstname }
                      </div>
                      <div className="list-item">
                        { booking.lastname }
                      </div>

                      <div className="btn btn-danger" onClick={ () => this.deleteBooking(booking.id) }>
                        Cancel Booking

                      </div>
                    </li>)
          }) }
      </ul>)
  }
  render() {
    return (
      <div className="App">
        <Header />
        <div className="form-inline booking-form">
          <div className="form-group">
            <input
              className="form-control"
              placeholder="Enter First Name"
              onChange={event =>
                this.setState({
                  firstname: event.target.value
                })
              }
            />
            <input
              className="form-control"
              placeholder="Enter Last Name"
              onChange={event =>
                this.setState({
                  lastname: event.target.value
                })
              }
            />
            <input
              className="form-control"
              type="datetime-local"
              onChange={event =>
                this.setState({
                  duedate: event.target.value
                })
              }
            />

            <button
              type="button"
              className="btn btn-success"
              onClick={() => this.addBooking()}
            >
              Add Booking
            </button>
          </div>
        </div>
        {this.renderBookings()}
      </div>
    );
  }
}

function mapStateToProps(state) {
  return {
    bookings: state
  };
}

export default connect(mapStateToProps, {
  addBooking,
  deleteBooking
})(App);

2 个答案:

答案 0 :(得分:1)

您只使用一个参数调用addBooking函数,但调用它两次。它返回两个操作,每个值分配给firstname。相反,请执行以下操作:this.props.addBooking(this.state.firstname, this.state.lastname);。这将解决您的问题。

答案 1 :(得分:0)

由于您使用App包裹connectApp现在可以执行dispatch次操作。可以使用dispatch通过道具访问this.props.dispatch。因此,而不是this.props.addBooking使用this.props.dispatch(addBooking())

您也可以编辑

export default connect(mapStateToProps, {
  addBooking,
  deleteBooking
})(App);

export default connect()(App)

有关连接here的更多信息。 Connect用于挑选商店的特定部分,并将它们暴露给您正在包装的任何组件。在这种情况下,您只想使用您的操作,并将它们导入App.jsx

的顶部

即使你正在调用addBooking()/ deleteBooking(),它也没有流经正确的通道(dispatch)以便Redux知道更新商店,因此值会以未定义的形式返回。

相关问题