javascript 使用React时发现的奇怪问题

pftdvrlh  于 2023-05-27  发布在  Java
关注(0)|答案(1)|浏览(96)
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div id="root"></div>
    <!-- react -->
    <script
      crossorigin
      src="https://unpkg.com/react@18/umd/react.development.js"
    ></script>
    <script
      crossorigin
      src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"
    ></script>
    <!-- babel -->
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

    <script type="text/babel">
      class App extends React.Component {
        constructor(props) {
          super(props)
          this.state = { text: "Hello,World" }
          this.titleRef = React.createRef()
        }
        changeText() {
          // Get node information through ref
          // Print output before setState. => `<h2>5555</h2>`
          console.log(this.titleRef.current)
          // {text:"Hello,World"}
          console.log(this.state)           
          this.setState((state) => {
            return { text: "5555" }
          })
        }
        render() {
          const { text } = this.state
          return (
            <div>
              <h2 ref={this.titleRef}>{text}</h2>
              <button
                onClick={() => {
                  this.changeText()
                }}
              >
                change text
              </button>
            </div>
          )
        }
      }
      const root = ReactDOM.createRoot(document.querySelector("#root"))
      root.render(<App />)
    </script>
  </body>
</html>

在changeText方法中,我期望第一个console.log输出是Hello,World,因为它在setState之前,并且状态数据还没有改变。因此,我认为DOM仍然包含Hello,World。然而,实际输出是5555。我想知道发生了什么?
DOM的变化似乎发生在setState之前,这与我的理解不同。我一定是误会了什么。

z3yyvxxp

z3yyvxxp1#

(我不得不把这个作为一个答案,虽然我不确定它是否足够好,作为一个合格的,我需要一个更有经验的成员的一点帮助,以改善这一点。
但看起来好像有某种竞争状况在发生。我想这是因为获取this.titleRef.current的值(来自物理DOM)的成本非常高
我将您的代码转换为一个片段,但请看下面的屏幕截图。它清楚地显示了代码段内的控制台具有this.titleRef.current的“正确值”,但代码段外(主浏览器控制台)显示了this.titleRef.current的“不正确值”。

<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div id="root"></div>
    <!-- react -->
    <script
      crossorigin
      src="https://unpkg.com/react@18/umd/react.development.js"
    ></script>
    <script
      crossorigin
      src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"
    ></script>
    <!-- babel -->
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

    <script type="text/babel">
      class App extends React.Component {
        constructor(props) {
          super(props)
          this.state = { text: "Hello,World" }
          this.titleRef = React.createRef()
        }
        changeText() {
          // Get node information through ref
          // Print output before setState. => `<h2>5555</h2>`
          console.log(this.titleRef.current)
          // {text:"Hello,World"}
          console.log(this.state)           
          this.setState((state) => {
            return { text: "5555" }
          })
        }
        render() {
          const { text } = this.state
          return (
            <div>
              <h2 ref={this.titleRef}>{text}</h2>
              <button
                onClick={() => {
                  this.changeText()
                }}
              >
                change text
              </button>
            </div>
          )
        }
      }
      const root = ReactDOM.createRoot(document.querySelector("#root"))
      root.render(<App />)
    </script>
  </body>
</html>

我想更多地了解为什么你想要在任何给定时刻this.titleRef.current的值,特别是在状态更新之前...

相关问题