React类组件中setState依赖其他state值时无输出问题咨询
问题原因
- 核心原因是
window.navigator.geolocation.getCurrentPosition是异步API,你写在构造函数里的message计算逻辑是同步执行的,只会在组件实例初始化时跑一次:- 构造函数执行时,定位请求刚发出去,成功/失败回调还没触发,
this.state.lat还是初始值null、errorMessage还是空字符串,所以你的判断逻辑只会走到else分支,把message设为Loading... - 后续定位完成、回调触发时,你只更新了
lat或者errorMessage的值,没有写任何逻辑同步更新message字段,所以render里拿到的message永远不会变化,自然不会输出预期内容。
- 构造函数执行时,定位请求刚发出去,成功/失败回调还没触发,
- 额外注意:构造函数中不需要调用
setState,直接给this.state赋值初始化即可,你在构造函数里调用setState属于多余操作,也不会触发额外的重渲染。
修复方案
你可以选任意一种方式修改:
- 把
message的计算逻辑放到render方法里(和你第一个正常运行的版本逻辑一致):
class App extends React.Component { constructor(props) { super(props); this.state = { lat: null, errorMessage: "" }; window.navigator.geolocation.getCurrentPosition( (position) => this.setState({ lat: position.coords.latitude }), (err) => this.setState({ errorMessage: err.message }) ); } render() { let message = "" if (this.state.lat && !this.state.errorMessage) { message = "Latitude: " + this.state.lat } else if (!this.state.lat && this.state.errorMessage) { message = "Error: " + this.state.errorMessage } else { message = "Loading..." } return <div> {message} </div>; } }
- 在定位的回调函数中同步更新
message:
class App extends React.Component { constructor(props) { super(props); this.state = { lat: null, errorMessage: "", message: "Loading..." }; window.navigator.geolocation.getCurrentPosition( (position) => { const lat = position.coords.latitude this.setState({ lat, message: "Latitude: " + lat }) }, (err) => { const errorMessage = err.message this.setState({ errorMessage, message: "Error: " + errorMessage }) } ); } render() { return <div> {this.state.message} </div>; } }
内容的提问来源于stack exchange,提问作者user17060738
相关产品推荐
相关产品推荐

