Home > Mobile >  Can't Get React Component to Update or Pass Prop
Can't Get React Component to Update or Pass Prop

Time:11-24

All the code does is to update a counter 1 every time you click in the button, the problem here is when i'm trying to pass the prop counter to text it does not update in the Text component i've been doing some research and look like i have to wake it up with another function, if someone could explain me, i would be really grateful.

import React from 'react';
import ReactDOM from 'react-dom';

class Button extends React.Component {
  constructor(props) {
    super(props)
    this.state = {counter: 1}
  }
  render() {
    return (
      <button onClick={() => {
        this.setState({
          counter: this.state.counter 1
        });

          //tries passing  the prop counter with the state of the counter
          <Text counter={this.state.counter} /> 
          
    }}>
        Click here
      </button>
    )
  }
}
class Text extends React.Component {
  render() {
    return (
      // returns 'clicked undefined times'
      <h2 id='counter-text'>{'Clicked '   this.props.counter   ' times'}</h2>
    )
  }
}
class App extends React.Component {
  render() {
    return (
      <>
        <Text/>
        <Button/>
      </>
    )
  }
}

ReactDOM.render(<App/>,document.getElementById('root'));

CodePudding user response:

Well, the code is syntactically wrong. You cannot render a Text in the onChange method of a button.

What you wanted was, when the count is updated in the Button, it should reflect in another component, i.e., the Text.

As these two are different components altogether, you have to have a shared state for them.

And for that, you can lift the counter state from Button to a parent component App. Check this out: https://reactjs.org/docs/lifting-state-up.html

This should work:

import React from "react";
import ReactDOM from "react-dom";

class Button extends React.Component {
  render() {
    // 3. on every click, Button uses App's updater method to update the count
    return <button onClick={this.props.handleCounter}>Click here</button>;
  }
}
class Text extends React.Component {
  render() {
    return (
      <h2 id="counter-text">{"Clicked "   this.props.counter   " times"}</h2>
    );
  }
}

// 1. Let App bear the counter state
class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { counter: 1 };
    this.handleCounter = this.handleCounter.bind(this);
  }

  handleCounter() {
    this.setState({
      counter: this.state.counter   1
    });
  }

  // 2. Let the Button and Text components share the App state
  render() {
    return (
      <>
        <Text counter={this.state.counter} />
        <Button
          counter={this.state.counter}
          handleCounter={this.handleCounter}
        />
      </>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("root"));

CodePudding user response:

There's a few mistakes on how your code is written. I've changed it slightly and put it on a sandbox you can play around with.

What's wrong:

  • You're trying to render <Text counter={this.state.counter} /> from within the onClick callback for the button, but this won't ever render without being inside the return statement of a render function.
  • You're using state inside the Button component, but Text component is not a child of this component.
    • Both Button and Text are children of App, and both of them need to access this counter state, so App should have the state and pass it as prop for Text
    • Button needs a callback to be able to update it's parent (App) state. You can pass a function that does this as a prop to Button and then call this on onClick.
  • Related