簡體   English   中英

Class 組件 ReactJS - setTimeout 在 class 組件中得到錯誤的值

[英]Class Component ReactJS - setTimeout get wrong value in class component

應用組件:

class App extends React.Component {
        constructor() {
          super();
            this.state = {
            user: 'Dan',
          };
        }
        render() {
          return (
            <React.Fragment>
              <label>
                <b>Choose profile to view: </b>
                <select
                  value={this.state.user}
                  onChange={e => this.setState({ user: e.target.value })}
                >
                  <option value="Dan">Dan</option>
                  <option value="Sophie">Sophie</option>
                  <option value="Sunil">Sunil</option>
                </select>
              </label>
              <h1>Welcome to {this.state.user}’s profile!</h1>
              <p>
                <ProfilePageClass user={this.state.user} />
                <b> (class)</b>
              </p>
            </React.Fragment>
          )
        }
      }

ProfilePageClass(問題出在這里):

class ProfilePageClass extends React.Component {
  showMessage = () => {
    alert('Followed ' + this.props.user); // This get wrong value (new props)
  };

  handleClick = () => {
    setTimeout(this.showMessage, 6000); // This get wrong value (new props)
  };

  render() {
    return <button onClick={this.handleClick}>Follow</button>;
  }
}

setTimeout 不顯示原來被關注的用戶對應的消息

我認為這是 props 或 this 的問題,但我不確定。

誰能告訴我這是怎么回事?

this關鍵字無關。 當應用程序 state 更改時,您的組件實例會收到新的props值,並且在更改后運行的setTimeout回調將訪問新值。 這有時是可取的,有時不是。

這是function 組件和class組件之間的區別之一。 要獲取單擊按鈕時呈現的用戶配置文件,您需要在單擊(或呈現)按鈕時明確記住它:

class ProfilePageClass extends React.Component {    
  handleClick = () => {
    const user = this.props.user;
//  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    setTimeout(() => {
      alert('Followed ' + this.props.user); // current value (wrong)
      alert('Followed ' + user); // old value (expected)
    }, 6000);
  };

  render() {
    return <button onClick={this.handleClick}>Follow</button>;
  }
}

使用 function 組件,您不會弄錯(但如果沒有useRef訪問當前值幾乎是不可能的):

function ProfilePageClass({user}) {    
  const handleClick = () => {
    setTimeout(() => {
      alert('Followed ' + user); // old value (expected)
    }, 6000);
  };
  return <button onClick={this.handleClick}>Follow</button>;
}

您使用的setTimeout可能存在問題,您正在失去對您希望顯示的實際道具的引用。 您可以將類似這樣的內容添加到您的父組件中:

this.myRef = React.createRef();

這將生成一個 ref,您稍后可以將其傳遞給子組件。 您可以以這種方式設置 refs 當前項:

this.myRef.current = this.state.user

為了填充參考。

試試這個修改,因為handleClick可能不是自動綁定。

import React from "react";
export default class App extends React.Component {

  constructor(props) {
    super(props);
      this.state = {
      user: 'Dan',
    };
  }
  render() {
    return (
      <React.Fragment>
        <label>
          <b>Choose profile to view: </b>
          <select
            value={this.state.user}
            onChange={e => this.setState({ user: e.target.value })}
          >
            <option value="Dan">Dan</option>
            <option value="Sophie">Sophie</option>
            <option value="Sunil">Sunil</option>
          </select>
        </label>
        <h1>Welcome to {this.state.user}’s profile!</h1>
        <p>
          <ProfilePageClass user={this.state.user} />
          <b> (class)</b>
        </p>
      </React.Fragment>
    )
  }
}

配置文件警報

class ProfilePageClass extends React.Component {
//Define a constructor here
  constructor(props){
    super(props)
// Bind handleClick , so that `this` will point to parent component when you pass to child
    this.handleClick= this.handleClick.bind();
  }
  showMessage = () => {
    alert('Followed ' + this.props.user); // This get value (new props)
  };

  handleClick = () => {
    setTimeout(this.showMessage, 100); // This get  value (new props)
  };

  render() {
    return <button onClick={this.handleClick}>Follow</button>;
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM