在 REACT 中将 setState 设置为另一个状态值
Setting a setState to another state value in REACT
我有一个关于在 class 组件中使用状态的 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>
第二种方式有什么问题?
两个主要问题:
1) setState
是异步的
即使第二个问题不存在,你也不能在调用 setState
后立即反省状态;状态尚未设置。
2) getCurrentPosition
是异步的
getCurrentPosition
的回调将在未来的不确定时间执行。构造函数继续 运行,在 getCurrentPosition
可能调用其回调之前调用 setState
(基于当前状态,初始化为 null 和空字符串)。
(并且在构造函数本身中调用 setState
的理由为零(与 getCurrentPosition
的回调相反,这很好),您可以直接设置状态首先初始化它。
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>;
}
}
我有一个关于在 class 组件中使用状态的 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>
第二种方式有什么问题?
两个主要问题:
1) setState
是异步的
即使第二个问题不存在,你也不能在调用 setState
后立即反省状态;状态尚未设置。
2) getCurrentPosition
是异步的
getCurrentPosition
的回调将在未来的不确定时间执行。构造函数继续 运行,在 getCurrentPosition
可能调用其回调之前调用 setState
(基于当前状态,初始化为 null 和空字符串)。
(并且在构造函数本身中调用 setState
的理由为零(与 getCurrentPosition
的回调相反,这很好),您可以直接设置状态首先初始化它。
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>;
}
}