在尝试使用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};
组件(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);
答案 0 :(得分:1)
您只使用一个参数调用addBooking
函数,但调用它两次。它返回两个操作,每个值分配给firstname
。相反,请执行以下操作:this.props.addBooking(this.state.firstname, this.state.lastname);
。这将解决您的问题。
答案 1 :(得分:0)
由于您使用App
包裹connect
,App
现在可以执行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知道更新商店,因此值会以未定义的形式返回。