单击按钮时,应通过以下功能将文本“第二条消息”和“第三条消息”添加到状态:
root@swarm-master-784816DA-0:~# docker run -d -p 80:80 yeasy/simple-web
0226e9ab3cadf20701f64c02f1f4a42f5fd57fd297722f268db47db1b124ab5c
root@swarm-master-784816DA-0:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0226e9ab3cad yeasy/simple-web "/bin/sh -c 'pytho..." 6 seconds ago Up 5 seconds 10.0.0.5:80->80/tcp swarm-agent-784816DA000001/stupefied_snyder
但其中只有一人正在开火。
我创建了一个显示问题的简单代码段。
class Button extends React.Component {
constructor(props) {
super(props);
this.addMessage = this.addMessage.bind(this);
}
addMessage() {
this.props.addMessage('second message'); // This is ignored
this.props.addMessage('third message'); // Only this message is added
}
render() {
return(
<button onClick={this.addMessage}>Add text</button>
)
}
}
class Button extends React.Component {
constructor(props) {
super(props);
this.addMessage = this.addMessage.bind(this);
}
addMessage() {
this.props.addMessage('second message'); // This is ignored
this.props.addMessage('third message'); // Only this message is added
}
render() {
return(
<button onClick={this.addMessage}>Add text</button>
)
}
}
class Messages extends React.Component {
constructor(props) {
super(props);
}
render() {
return(
<p>{this.props.message}</p>
)
}
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
messages: [{
text: 'first message'
}]
}
this.addMessage = this.addMessage.bind(this);
}
addMessage(message) {
let messages = this.state.messages.slice();
messages.push({text:message});
this.setState({messages: messages});
}
render() {
let messages = [];
this.state.messages.forEach((message) => {
messages.push(<Messages message={message.text}></Messages>);
});
return(
<div>
{messages}
<Button addMessage={this.addMessage} />
</div>
)
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
提前致谢!
答案 0 :(得分:3)
引自reactjs docs about state updates:
React可以将多个
setState()
个调用批处理为一个更新 性能由于
this.props
和this.state
可以异步更新,你 不应该依赖他们的价值来计算下一个州。
您对addMessage()
的第二次通话使用this.state
来设置新状态。但是因为setState()
是异步的,我的状态还没有更新,导致你的第二次调用覆盖了你的第一个:
addMessage(message) {
// here you access this.state which hasn't been updated yet in your second call
let messages = this.state.messages.slice();
messages.push({text: message});
this.setState({messages: messages});
}
要修复它,请使用接受函数的第二种
setState()
形式 而不是一个对象。该功能将接收先前的状态 作为第一个参数,以及应用更新时的道具 作为第二个论点:
使用传递前一状态的箭头函数,包括先前调用setState()
的更改以计算新状态。这将解决您的问题。
使用es6传播语法:
this.setState((prevState, props) => ({
messages: [...prevState.messages, {text: message}]
}));
使用slice()
:
this.setState((prevState, props) => {
let messages = prevState.messages.slice();
messages.push({text:message});
return {messages};
});