[英]Setting a setState to another state value in REACT
我有一個關於在類組件中使用狀態的 React 練習。 當我編寫如下代碼時,我的解決方案運行良好:
import React from "react"; import "./App.css"; 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() { if (this.state.lat && !this.state.errorMessage) { return <div>Latitude: {this.state.lat}</div>; } else if (!this.state.lat && this.state.errorMessage) { return <div>Erroe: {this.state.errorMessage}</div>; } else { return <div>Latitude: Loading...</div>; } } } export default App;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
但是當我以另一種方式編寫它時,我沒有錯誤但沒有輸出
class App extends React.Component { constructor(props) { super(props); this.state = { lat: null, errorMessage: "", message: "" }; window.navigator.geolocation.getCurrentPosition( (position) => this.setState({ lat: position.coords.latitude }), (err) => this.setState({ errorMessage: err.message }) ); if (this.state.lat && !this.state.errorMessage) { this.setState({ message: "Latitude: " + this.state.lat }); } else if (!this.state.lat && this.state.errorMessage) { this.setState({ message: "Error: " + this.state.errorMessage }); } else { this.setState({ message: "Loading..." }); } } render() { return <div> {this.state.message} </div>; } }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
第二種方式有什么問題?
setState
是異步的。 this.state
在下一次渲染中獲得新值,但您正在嘗試立即使用它。
如果您想在狀態中存儲消息,您可以在傳遞給getCurrentPosition
的回調中執行此操作,並且最好在ComponentDidMount
而不是構造函數中處理所有這些。
import { Component } from "react";
import "./styles.css";
export default class App extends Component {
constructor(props) {
super(props);
this.state = { lat: null, errorMessage: "", message: "" };
}
componentDidMount() {
window.navigator.geolocation.getCurrentPosition(
(position) => {
const lat = position.coords.latitude;
this.setState({ lat, message: `Latitude: ${lat}` });
},
(err) =>
this.setState({
errorMessage: err.message,
message: `Error: ${err.message}`
})
);
}
render() {
return <div> {this.state.message} </div>;
}
}
兩個主要問題:
1) setState
是異步的
即使第二個問題不存在,您也不能在調用setState
后立即內省狀態; 狀態尚未設置。
2) getCurrentPosition
是異步的
getCurrentPosition
的回調將在未來的不確定時間執行。 構造函數繼續運行,在getCurrentPosition
可能調用其回調之前調用setState
(基於當前狀態,初始化為空值和空字符串)。
(並且在構造函數本身中調用setState
的理由為零(與getCurrentPosition
的回調相反,這很好),您可以像第一次初始化時那樣直接設置狀態。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.