Я создаю простое приложение для контактов, используя React и Redux.Мой объект состояния выглядит следующим образом:
{
"contacts": [
{
"name": "Miguel Camilo",
"phone": "123456789"
},
{
"name": "Peter",
"phone": "883292300348"
},
{
"name": "Jessica",
"phone": "8743847638473"
},
{
"name": "Michael",
"phone": "0988765553"
}
],
"activeContact": {
"name": "Peter",
"phone": "883292300348"
}
}
Я пытаюсь создать функцию добавления контактов, которая будет брать имя и номер из входных данных на странице и добавлять их в массив contacts
в состоянии,Вот как это построено:
Компонент ContactsList:
class ContactList extends Component {
renderList() {
return this.props.contacts.map((contact) => {
return (
<li
key={contact.phone}
onClick={() => this.props.selectContact(contact)}
className='list-group-item'>{contact.name}</li>
);
});
}
render() {
return (
<ul className = 'list-group col-sm-4'>
{this.renderList()}
</ul>
);
}
}
function mapStateToProps(state) {
return {
contacts: state.contacts
};
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({ selectContact: selectContact }, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(ContactList)
AddContactsComponent:
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) {
console.log('mapstatetoprops:');
console.log(state);
return {
contacts: state.contacts
};
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({ addContact: addContact }, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(AddContactModal)
Редуктор контактов (содержащий обработчик ADD_CONTACT):
export default function (state = { contacts : [] }, action) {
switch (action.type) {
case 'ADD_CONTACT':
console.log(state);
return Object.assign({}, state, {
contacts: state.concat([
{
name: action.payload.name,
phone: action.payload.phone
}
])
})
default:
return state;
}
}
Приложение index.js, в котором построен магазин:
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'));
И объединение моих редукторов:
const rootReducer = combineReducers({
contacts: ContactsReducer,
activeContact: ActiveContactReducer
});
export default rootReducer;
Моя проблема заключается в том, что, когда я нажимаю на кнопку Добавить контакт, новыйМассив contacts
добавляется в существующий массив contacts
в состоянии, а затем по какой-то странной причине мой начальный список контактов добавляется на верхнем уровне состояния.Таким образом, после нажатия кнопки «Добавить контакт» (и до того, как произойдет ошибка), когда я регистрирую this.props.contacts
, это выглядит следующим образом:
{
"0": {
"name": "Miguel Camilo",
"phone": "123456789"
},
"1": {
"name": "Peter",
"phone": "883292300348"
},
"2": {
"name": "Jessica",
"phone": "8743847638473"
},
"3": {
"name": "Michael",
"phone": "0988765553"
},
"contacts": [
{
"name": "Miguel Camilo",
"phone": "123456789"
},
{
"name": "Peter",
"phone": "883292300348"
},
{
"name": "Jessica",
"phone": "8743847638473"
},
{
"name": "Michael",
"phone": "0988765553"
},
{
"name": "123",
"phone": "123"
}
]
}
Итак, новый массив contacts
был добавлен в исходный contacts
массив, содержащий исходные значения плюс новое.Хотя исходный массив contacts
остается неизменным.
Я не уверен, почему это так.Первоначально я думал, что объект state
, передаваемый моему редуктору, является полным состоянием, но, похоже, это только часть моего состояния contacts
, поэтому я изменил свой вызов Object.assign (), чтобы учесть это, изменив его.от contacts: state.contacts.concat()
до contacts: state.concat()
, но это все еще не решило проблему.
Я хочу, чтобы состояние, которое возвращается к моему компоненту ContactsList, выглядело так:
{
"contacts": [
{
"name": "Miguel Camilo",
"phone": "123456789"
},
{
"name": "Peter",
"phone": "883292300348"
},
{
"name": "Jessica",
"phone": "8743847638473"
},
{
"name": "Michael",
"phone": "0988765553"
},
{
"name": "this is the new contact",
"phone": "123"
}
],
"activeContact": {
"name": "Peter",
"phone": "883292300348"
}
}
Только оригиналсостояние с одним дополнительным контактом, добавленным в мой массив contacts
.Есть идеи, что не так с моей реализацией?Любая помощь приветствуется!