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
andText
are children ofApp
, and both of them need to access this counter state, so App should have the state and pass it as prop forText
- 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 ononClick
.
- Both