В моем коде есть следующий компонент:
class ContactsList extends Component {
constructor(props) {
super(props);
this.state = {
contactItems: [
<ContactItem key = "Lena" login = "typeofweb1" name = "Lena" department = "JavaScript Developer" border = "0" />,
<ContactItem key = "Brian" login = "typeofweb2" name = "Brian" department = "Human Resources" />,
<ContactItem key = "Rick" login = "typeofweb3" name = "Rick" department = "QA" />
]
};
}
render() {
return (
<ul className = "list-group list-group-flush container">
{this.state.contactItems}
<button type = "button" onClick = {this.addContactItem}>
Add
</button>
</ul>
);
}
addContactItem = () => {
console.info(this.state.contactItems);
this.state.contactItems.push(<ContactItem key = "Rick" login = "typeofweb3" name = "Rick" department = "QA" />);
this.setState({ contactItems: this.state.contactItems });
};
}
Проблема заключается в том, что компонент не обновляется даже при изменении состояния (я вижу, что в console.info массив contactItems получает новые элементы). Есть проблема с .push (), потому что если просто изменить setState на что-то вроде
this.setState({ contactItems: ["something"]});
тогда все работает правильно.
Вы изменяете свой массив. React должен иметь новый массив, чтобы знать, что реквизиты изменились
почему вы одновременно нажимаете и обновляете состояние ??
Как мне тогда это сделать? addContactItem = () => {this.newArray = this.state.contactItems; this.newArray.push (<ContactItem key = "Rick" login = "typeofweb3" name = "Rick" Department = "QA" />); this.setState ({contactItems: this.newArray}); }; Это не помогает
это не новый массив, таким образом вы копируете указатель на тот же объект. var dup_array = original_array.slice();



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы не должны изменять состояние в react. Вы можете использовать это так:
addContactItem = () => {
this.setState({ contactItems: [
...this.state.contactItems, // clone the state,
// then, add new item
<ContactItem key = "Rick" login = "typeofweb3" name = "Rick" department = "QA" />
]
});
};
когда вам нужно вычислить новое значение состояния на основе некоторого предыдущего значения состояния, вы должны передать функцию обратного вызова методу this.setState вместо прямого чтения из this.state. В противном случае велика вероятность получить несинхронизированные данные. См. Дополнительную информацию в официальной документации: reactjs.org/docs/react-component.html#setstate
Я точно не знаю почему, но это работает:
class ContactsList extends Component {
constructor(props) {
super(props);
this.state = {
contactItems: [
<ContactItem key = "Lena" login = "typeofweb1" name = "Lena" department = "JavaScript Developer" border = "0" />,
<ContactItem key = "Brian" login = "typeofweb2" name = "Brian" department = "Human Resources" />,
<ContactItem key = "Rick" login = "typeofweb3" name = "Rick" department = "QA" />
]
};
}
render() {
return (
<ul className = "list-group list-group-flush container">
{this.state.contactItems}
<button type = "button" onClick = {this.addContactItem}>
Add
</button>
</ul>
);
}
addContactItem = () => {
this.setState(prevState => ({
contactItems: prevState.contactItems.concat([<ContactItem key = "Rick" login = "typeofweb3" name = "Rick" department = "QA" />])
}));
};
}
Может кто-нибудь объяснить мне, почему следующий код работает, а предыдущий - нет?
Да, это сработает, потому что мутации сейчас нет. Потому что вы используете concat, который похож на мой ответ с использованием оператора распространения.
Раньше я пытался скопировать массив и нажать на новый массив, но он все равно не работал, даже несмотря на то, что я обновил состояние с новым массивом, а не с текущим находящимся в состоянии
стандартная проблема изменения существующего объекта