简体   繁体   English

在 REACT 中将 setState 设置为另一个状态值

[英]Setting a setState to another state value in REACT

I have a React exercise about using states in class components.我有一个关于在类组件中使用状态的 React 练习。 My solution works well when I code as below:当我编写如下代码时,我的解决方案运行良好:

 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>

But when I write it in another way, I get no error but no output但是当我以另一种方式编写它时,我没有错误但没有输出

 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>

What is the problem by the second way?第二种方式有什么问题?

setState is async. setState是异步的。 this.state gets the new value in the next render but you're trying to use it right away. this.state在下一次渲染中获得新值,但您正在尝试立即使用它。

If you want to store the message in the state, you can do that in the callbacks passed to getCurrentPosition and it is better to handle all that in ComponentDidMount rather than the constructor.如果您想在状态中存储消息,您可以在传递给getCurrentPosition的回调中执行此操作,并且最好在ComponentDidMount而不是构造函数中处理所有这些。

编辑 agitated-pond-rv6u2

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>;
  }
}

Two main issues:两个主要问题:

1) setState is asynchronous 1) setState是异步的

Even if the second problem didn't exist you cannot immediately introspect state immediately after calling setState ;即使第二个问题不存在,您也不能在调用setState后立即内省状态; the state won't have been set yet.状态尚未设置。

2) getCurrentPosition is asynchronous 2) getCurrentPosition是异步的

The callbacks for getCurrentPosition will execute at an indeterminate time in the future. getCurrentPosition的回调将在未来的不确定时间执行。 The constructor continues to run, calling setState (based on current state, initialized to nulls and empty strings) before getCurrentPosition has likely called its callbacks.构造函数继续运行,在getCurrentPosition可能调用其回调之前调用setState (基于当前状态,初始化为空值和空字符串)。

(And there's zero reason to call setState in the constructor itself (as opposed to the callbacks to getCurrentPosition , which is fine), you can just set state directly as you do when you first initialize it. (并且在构造函数本身中调用setState的理由为零(与getCurrentPosition的回调相反,这很好),您可以像第一次初始化时那样直接设置状态。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM