import React from "react";
import io from "socket.io-client";
class TrafficLight extends React.PureComponent {
state = { lamp: null, currentcolor: "red" };
// turnLampOn event handler
turnLampOn = async () => {
while (true) {
//如果我尝试在Heroku上的生产环境中运行此应用,则会在此处显示Null错误
// currentcolor=red wait 'red' ms and enable 'green'
await this.waitSomeSeconds("green", this.state.lamp.red);
// currentcolor=green wait 'green' ms and enable 'yellow'
await this.waitSomeSeconds("yellow", this.state.lamp.green);
// currentcolor=yellow wait 'yellow' ms and enable 'red'
await this.waitSomeSeconds("red", this.state.lamp.yellow);
}
};
waitSomeSeconds = (color, wait) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(
this.props.street +
": from " +
this.state.currentcolor +
" to " +
color +
", wait=" +
wait
);
this.setState({ currentcolor: color });
resolve();
}, wait);
});
};
componentDidMount = async () => {
// connect to server
//let socket = io.connect("localhost:5000", { forceNew: true });
// send join message to server, pass a payload to it (street name specified via props)
// connect to server on Heroku cloud
const socket = io.connect();
socket.emit("join", { streetName: this.props.street }, err => {});
// wait on 'turnLampOn'
socket.on("turnLampOn", lampData => {
console.log("turnLampOn", lampData);
// Set new lamp data and start trafficlight
if (this.state.lamp === null) {
this.setState({ lamp: lampData });
//当应用程序尝试执行此方法时,将出现空值。
this.turnLampOn();
}
});
};
// Get current color helper
getColor = color => (this.state.currentcolor === color ? color : "white");
render() {
return (
<div className="light">
<div
className="lamp"
style={{ backgroundColor: this.getColor("red"), margin: ".5rem" }}
/>
<div
className="lamp"
style={{ backgroundColor: this.getColor("yellow"), margin: ".5rem" }}
/>
<div
className="lamp"
style={{ backgroundColor: this.getColor("green"), margin: ".5rem" }}
/>
<div style={{ textAlign: "center", fontName: "Helvetica" }}>
{this.props.street}
</div>
</div>
);
}
}
export default TrafficLight;
此应用在开发模式下运行良好,错误在生产环境中发生。 该应用程序具有一个Node.js服务器,其中包含用于建立连接的sockect.io
答案 0 :(得分:1)
React的setState函数是异步的,不会立即更新状态。根据文档
将setState()视为请求而不是立即命令来更新组件。为了获得更好的感知性能,React可能会延迟它,然后在一次通过中更新几个组件。 React不能保证状态更改会立即应用。
setState()并不总是立即更新组件。它可能会批量更新或将更新推迟到以后。这使得在调用setState()之后立即读取this.state可能是一个陷阱。而是使用componentDidUpdate或setState回调(setState(updater,callback)),确保在应用更新后均能触发这两种方法。如果需要基于先前的状态来设置状态,请阅读以下有关updater参数的信息。
有关更多信息,请查看here。
要解决您的问题,请在before.plot.new
的回调中调用turnLampOn
方法
setState