我正在构建一个非常简单的联系人应用程序,以熟悉React和Redux。现在,我正在尝试构建添加联系人的功能。我以为我已正确设置了动作和减速器,但当前传递给减速器的状态为null。我希望当前的联系人列表处于通过状态。如果在执行reducer后记录状态,甚至没有得到我希望添加的一个联系人,则该状态仍然为空。当我在输入字段中添加一些文本并单击“添加联系人”时,出现错误Cannot convert undefined or null to object
在添加接触式减速器中,传入的状态为null,我认为这是我的问题。我希望该化简器将状态作为当前联系人列表,添加到有效负载中包含的联系人中,然后返回包含此完整列表的新状态。
我的代码如下
操作:
function addContact(contact) {
console.log("it gets to the action");
return {
type: 'ADD_CONTACT',
payload: contact
}
}
export default addContact;
AddContacts Reducer:
export default function (state = {}, action) {
console.log(state);
switch (action.type) {
case 'ADD_CONTACT':
return Object.assign({}, state, {
contacts: [
...state.contacts,
{
name: action.payload.name,
phone: action.payload.phone
}
]
})
}
return state;
}
调用此操作的组件:
import React, { Component } from 'react'
import AddContactButton from './AddContactButton';
import { connect } from 'react-redux'
import addContact from '../actions/action_add_contact'
import { bindActionCreators } from 'redux'
class AddContactModal extends Component {
constructor() {
super();
this.state = {firstName: "", phone: ""};
}
handleNameChange(event) {
this.setState({firstName: event.target.value})
}
handlePhoneChange(event) {
this.setState({phone: event.target.value});
}
render() {
return(
<div>
<input type="text" className="name" placeholder="Contact Name" onChange={(event) => this.handleNameChange(event)}/>
<input type="text" className="phone" placeholder="Contact Phone" onChange={(event) => this.handlePhoneChange(event)}/>
<AddContactButton firstName={this.state.firstName} firstName={this.state.phone} onClick={() => this.props.addContact({"name": this.state.firstName, "phone": this.state.phone})}/>
</div>
);
}
}
function mapStateToProps(state) {
return {
contacts: state.contacts
};
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({ addContact: addContact }, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(AddContactModal)
创建商店:
const createStoreWithMiddleware = applyMiddleware()(createStore);
const initialState = {
"contacts": [
{
"name": "Miguel Camilo",
"phone": "123456789"
},
{
"name": "Peter",
"phone": "883292300348"
},
{
"name": "Jessica",
"phone": "8743847638473"
},
{
"name": "Michael",
"phone": "0988765553"
}
],
"activeContact": null
};
ReactDOM.render(
<Provider store={ createStoreWithMiddleware(reducers, initialState) }>
<App />
</Provider>
, document.querySelector('.container'));
Contacts reducer,它仅返回硬编码的联系人列表以设置初始状态:
export default function () {
return [{
"name": "Miguel Camilo",
"phone": "123456789"
},{
"name": "Peter",
"phone": "883292300348"
},{
"name": "Jessica",
"phone": "8743847638473"
},{
"name": "Michael",
"phone": "0988765553"
}];
}
我很确定我的问题是由于我在组件中使用mapStateToProps和mapDispatchToProps而引起的,当我查看redux状态时,我看到它添加了一个我不想要的集合“ addContacts”?它不应该只是从操作中获取有效负载并将其添加到“联系人”集合中吗?
在mapStateToProps
函数中,我添加了一条打印语句以查看state
并由此得到结果。我不确定为什么存在该集合addContact[]
。我不希望这样,我只是希望addContact功能将联系人添加到现有的contacts[]
集合中。
{
"contacts": [
{
"name": "Miguel Camilo",
"phone": "123456789"
},
{
"name": "Peter",
"phone": "883292300348"
},
{
"name": "Jessica",
"phone": "8743847638473"
},
{
"name": "Michael",
"phone": "0988765553"
}
],
"activeContact": null,
"addContact": {}
}
答案 0 :(得分:1)
对于您的Reducer,请尝试以下更简单的方法:
export default function (state = {}, action) {
switch (action.type) {
case 'ADD_CONTACT':
return {
...state,
contacts: state.contacts.push(action.payload),
};
}
};
然后针对简单应用程序的mapDispatchToProps,它只能使用一个对象来工作。
例如。
const actions = { addContact };
export default connect(mapStateToProps, actions)(AddContactModal);
或更新当前代码:
function mapDispatchToProps(dispatch) {
return bindActionCreators({ addContact }, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(AddContactModal);
希望它会有所帮助;)。
我可以向您展示另一种构建商店并将其添加到提供程序的方法。因为您做事的方式与我习惯的有所不同。
最好的问候。