Home > Software engineering >  Class Component ReactJS - setTimeout get wrong value in class component
Class Component ReactJS - setTimeout get wrong value in class component

Time:01-27

App 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 (the problem is here):

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 does not display the message corresponding to the user that was originally followed

I think it's a problem with the props or this, but I'm not sure.

Can anyone tell me what is going on?

CodePudding user response:

Try this modification, as there might be handleClick is not auto bound.

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

Profile alert

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

CodePudding user response:

It's likely there's a problem regarding the setTimeout your using, in which you're losing reference to the actual prop you wish to display. You can add something like this to your parent component:

this.myRef = React.createRef();

This will generate a ref that you can later pass in to the child component. You can set the refs current item in this fashion:

this.myRef.current = this.state.user

in order to populate the ref.

  • Related