-1

I am trying to have a button inside a child class use setState on my parent class. However, it is not working and I am unsure why. When I click the button I receive a typeerror saying that it cannot read the property 'props' of undefined. enter image description here

Here is my code for the parent, I have left out unrelated code:

onButtonClick() {
      this.setState({showingLoadingScreen: false})
  }
//unrelated code between
render() {
    return (
    <div>
      <header className="App-header">
        <Loading visible={this.state.showingLoadingScreen} onButtonClick={this.onButtonClick} />
      </header>
      <Map
//unrelated code between

Here is my code for the child, button code is marked with comments:

//import statements

const defaultOptions = {
  loop: true,
  autoplay: true,
  animationData: loaderData.default,
  rendererSettings: {
    preserveAspectRatio: "xMidYMid slice"
  }
};

const defaultOptions2 = {
  loop: false,
  autoplay: true,
  animationData: doneData.default,
  rendererSettings: {
    preserveAspectRatio: "xMidYMid slice"
  }
};

export default class Loading extends Component {
  constructor(props) {
    super(props);
    this.state = {
      done: undefined
    };
  }

  onButtonClick() {
    this.props.onButtonClick();
  }
//button code
  componentDidMount() {
    setTimeout(() => {
      fetch("https://jsonplaceholder.typicode.com/posts")
        .then(response => response.json())
        .then(json => {
          this.setState({ loading: true });
          setTimeout(() => {
            this.setState({ done: true });
          }, 1000);
        });
    }, 2000);
  }

  render() {
    return (
      <div>
        {!this.state.done ? (
          <FadeIn> 
            <div class="d-flex justify-content-center align-items-center">
              <h1>Rendering Data</h1>
              {!this.state.loading ? (
                <Lottie options={defaultOptions} height={120} width={120} />
              ) : (
                <Lottie options={defaultOptions2} height={120} width={120} />
              )}
            </div>
          </FadeIn>
        ) : (
        <div>
          <FadeIn transitionDuration = {1000}><h1>Disclaimer</h1></FadeIn>
          <FadeIn transitionDuration = {1000}><p>Disclaiming</p></FadeIn>
          <button onClick={this.onButtonClick}>Continue</button>
//button code
        </div>
        )}
      </div>
    );
  }
}
ZKJ
  • 167
  • 4
  • 15
  • 1
    Does this answer your question? [React: "this" is undefined inside a component function](https://stackoverflow.com/questions/33973648/react-this-is-undefined-inside-a-component-function) – radulle Jun 22 '20 at 04:10

2 Answers2

1

The problem is this. You need to bind the function in the constructor like this:

this.onButtonClick= this.onButtonClick.bind(this)

More on this here https://reactjs.org/docs/handling-events.html

radulle
  • 1,437
  • 13
  • 19
1

onButtonClick() in child component is unnecessary, you can pass directly props function to button

<button onClick={this.props.onButtonClick}>Continue</button>
iamhuynq
  • 5,357
  • 1
  • 13
  • 36
  • I changed it. Now I have another error saying cannot read property setState of undefined. (from the onButtonClick function in the parent). Any idea of what the issue might be? – ZKJ Jun 22 '20 at 04:00
  • 1
    You need to `bind` it. Read the doc I provided and all will be clear. – radulle Jun 22 '20 at 04:09