Let's say I have three elements that hold in state a counter that increments when clicked.
If I click on one element, how do I reset the other counters to 0?
https://jsfiddle.net/69z2wepo/56827
const Parent = React.createClass({
render() {
const rows = [];
for (let i = 0; i < 3; i++) {
rows.push(<Child key={i} />);
}
return (
<ul>
{rows}
</ul>
);
}
});
const Child = React.createClass({
getInitialState() {
return {counter: 0};
},
handleClick() {
this.setState({counter: ++this.state.counter });
},
render() {
return (
<div onClick={this.handleClick}>
{this.state.counter}
</div>
);
}
});
ReactDOM.render(
<Parent />,
document.getElementById('app')
);
To reset a component to its initial state:Store the initial state in a variable. When an event occurs, call the setState() function, passing it the initial state.
The state is a variable like other variables in a JavaScript app. It is only accessible inside a component. You can pass the state to other child components, and you can also change the state from the child components.
React hooks are introduced in React 16.8. If you are familiar with the class components then there is no difference to change the parent component state from child component. In both cases, you have to pass the callback function to the parent.
It you really can't lift the state into the parent component as other answers have suggested, a hacky way to do this is to just change the key
prop of an element. This causes React to unmount the element with the old key
and mount a new instance.
class ChildComponent extends React.Component {
state = {
count: 0
};
render() {
const { count } = this.state;
return (
<div>
<div>count: {count}</div>
<button onClick={() => this.setState({ count: count + 1 })}>Increment</button>
</div>
);
}
}
class ParentComponent extends React.Component {
state = {
stateBustingKey: 0
};
render() {
const { stateBustingKey } = this.state;
return (
<div>
<ChildComponent key={stateBustingKey} />
<button
onClick={() =>
this.setState({ stateBustingKey: stateBustingKey + 1 })
}
>
Reset
</button>
</div>
);
}
}
ReactDOM.render(<ParentComponent />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root" />
Component parent
in this case should be managed the state of children
.
Check this:
const Parent = React.createClass({
getInitialState() {
return {counter: 0, id: 0};
},
handleClick(id) {
if(this.state.id == id){
this.setState({counter: ++this.state.counter, id: id });
} else {
this.setState({counter: 1, id: id });
}
},
getCounter(id){
if(id == this.state.id){
return this.state.counter;
} else {
return 0;
}
},
render() {
const rows = [];
for (let i = 0; i < 3; i++) {
rows.push(<Child key={i} counter={this.getCounter(i)} handleClick={this.handleClick} id={i} />);
}
return (
<ul>
{rows}
</ul>
);
}
});
const Child = React.createClass({
render() {
return (
<div onClick={this.props.handleClick.bind(null, this.props.id)}>
{this.props.counter}
</div>
);
}
});
ReactDOM.render(
<Parent />,
document.getElementById('app')
);
JsFiddle
That would be a little hard since your Child
components are managing their own state.
You can convert them into dumb components and manage their state in your Parent
component.
Something like this
const Parent = React.createClass({
getInitialState() {
return {counters: [0,0,0]};
},
handleClick(index){
let newCounterState = this.state.counters.map(() => 0);
newCounterState[index] = this.state.counters[index] + 1 ;
this.setState({counters : newCounterState})
},
render() {
const rows = this.state.counters.map((value,index) => (
<Child
key={index}
handleClick={() => this.handleClick(index)}
counter={value}
/>
))
return (
<ul>
{rows}
</ul>
);
}
});
const Child = ({counter,handleClick}) => (
<div onClick={handleClick}>
{counter}
</div>
)
ReactDOM.render(
<Parent />,
document.getElementById('app')
);
jsfiddle
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With