I have two react components and I'd like to call setState to set a state in the one Component but called in the other one. How do I do that?
Asked
Active
Viewed 7.1k times
29
-
Have a function that sets the state on the parent component and pass that function to the child component. – Shawn Yap Mar 06 '19 at 17:08
-
Possible duplicate: https://stackoverflow.com/questions/52983102/react-call-setstate-from-another-component – Anas Abu Farraj Mar 06 '19 at 17:18
2 Answers
58
If you work with functional components you can use hooks like useState
. Don't forget to "save" (memoize) the reference of your handler with useCallback
, it helps React avoid useless rerenders.
Functional component solution
// myContainer.js
import React, { useState } from 'react'
import MyChild from 'some/path/myChild'
function MyContainer() {
const [name, setName] = useState('foo')
return (
<MyChild name={name} onNameChange={setName} />
)
}
export default MyContainer
// myChild.js
import React, { useCallback } from 'react'
function MyChild({ name, onNameChange }) {
const handleInputChange = useCallback(event => {
onNameChange(event.target.value)
}, [onNameChange])
return (
<div>
<input type="text" onChange={handleInputChange} value={name} />
<div>The name is: {name}</div>
</div>
)
}
export default MyChild
In a class you can use handler (method) that contains some logic or function call(s). It help to keep your code maintainable.
Class component solution
// myContainer.js
import React, { Component } from 'react'
import MyChild from 'some/path/myChild'
class MyContainer extends Component {
state = {
name: 'foo'
}
handleNameChange = name => {
this.setState({ name })
}
render() {
return (
<MyChild name={this.state.name} onNameChange={this.handleNameChange} />
)
}
}
export default MyContainer
// myChild.js
import React, { Component } from 'react'
class MyChild extends Component {
handleInputChange = event => {
this.props.onNameChange(event.target.value)
}
render() {
return (
<div>
<input type="text" onChange={this.handleInputChange} value={this.props.name} />
<div>The name is: {this.props.name}</div>
</div>
)
}
}
export default MyChild

Tariq Mahamid
- 15
- 6

Alexandre Nicolas
- 1,851
- 17
- 19
-
Hi, my situation is the inverse. Trying to change state in child functional component from a button click on the parent functional component. Also, there are multiple child components with a button each in a loop. How would I make sure only one of them updates? Thanks in advance! – Sanjiv Pradhanang Jun 18 '21 at 00:14
-
1@SanjivPradhanang Perhaps you could open a question thread, expose your issue with code example. That would be easier to propose solutions. – Alexandre Nicolas Jun 24 '21 at 07:49
17
You can't directly call setState
on a parent component from a child component because the updating of a component state is restricted to the current component.
To handle this, simply pass a function from the parent to the child that contains setState
. So when you want to update the parent's state, just call that passed function.
A minimal example:
// Parent.jsx
import React, { Component } from 'react';
import Child from './Child';
class Parent extends Component {
constructor(props) {
super(props);
this.setChanged = this.setChanged.bind(this);
this.state = {
changed: false
}
}
// Function to set the parent's state
setChanged() {
this.setState({ changed: true });
}
render() {
return <Child setChanged={this.setChanged} />
}
}
// Child.js
import React from 'react';
function Child(props) {
return (
// When clicked, parent's setChanged function is called
<div onClick={() => props.setChanged()} />
)
}

Adam
- 3,829
- 1
- 21
- 31