React js изменить состояние дочернего компонента из родительского компонента
У меня есть два компонента:
Родительский компонент, из которого я хочу изменить состояние дочерних компонентов:
class ParentComponent extends Component {
toggleChildMenu() {
?????????
}
render() {
return (
<div>
<button onClick={toggleChildMenu.bind(this)}>
Toggle Menu from Parent
</button>
<ChildComponent />
</div>
);
}
}
И Детский компонент:
class ChildComponent extends Component {
constructor(props) {
super(props);
this.state = {
open: false;
}
}
toggleMenu() {
this.setState({
open: !this.state.open
});
}
render() {
return (
<Drawer open={this.state.open}/>
);
}
}
Мне нужно либо изменить дочерний компонент открыть из родительского компонента, либо вызвать дочерний компонент toggleMenu() из родительского компонента при нажатии кнопки в родительском компоненте?
Ответы
Ответ 1
Состояние должно управляться в родительском компоненте. Вы можете передать open
значение дочернему компоненту, добавив свойство.
class ParentComponent extends Component {
constructor(props) {
super(props);
this.state = {
open: false
};
this.toggleChildMenu = this.toggleChildMenu.bind(this);
}
toggleChildMenu() {
this.setState(state => ({
open: !state.open
}));
}
render() {
return (
<div>
<button onClick={this.toggleChildMenu}>
Toggle Menu from Parent
</button>
<ChildComponent open={this.state.open} />
</div>
);
}
}
class ChildComponent extends Component {
render() {
return (
<Drawer open={this.props.open}/>
);
}
}
Ответ 2
Родительский компонент может управлять дочерним состоянием, передавая реквизит дочернему элементу, и дочерний компонент преобразует этот реквизит в состояние с помощью componentWillReceiveProps.
class ParentComponent extends Component {
state = { drawerOpen: false }
toggleChildMenu = () => {
this.setState({ drawerOpen: !this.state.drawerOpen })
}
render() {
return (
<div>
<button onClick={this.toggleChildMenu}>Toggle Menu from Parent</button>
<ChildComponent drawerOpen={this.state.drawerOpen} />
</div>
)
}
}
class ChildComponent extends Component {
constructor(props) {
super(props)
this.state = {
open: false
}
}
componentWillReceiveProps(props) {
this.setState({ open: props.drawerOpen })
}
toggleMenu() {
this.setState({
open: !this.state.open
})
}
render() {
return <Drawer open={this.state.open} />
}
}
Ответ 3
Вышеприведенный ответ частично верен для меня, но в моем сценарии я хочу установить значение в состояние, потому что я использовал это значение для показа/переключения модального режима. Так что я использовал, как показано ниже. Надеюсь, это кому-нибудь поможет.
class Child extends React.Component {
state = {
visible:false
};
handleCancel = (e) => {
e.preventDefault();
this.setState({ visible: false });
};
componentDidMount() {
this.props.onRef(this)
}
componentWillUnmount() {
this.props.onRef(undefined)
}
method() {
this.setState({ visible: true });
}
render() {
return (<Modal title="My title?" visible={this.state.visible} onCancel={this.handleCancel}>
{"Content"}
</Modal>)
}
}
class Parent extends React.Component {
onClick = () => {
this.child.method() // do stuff
}
render() {
return (
<div>
<Child onRef={ref => (this.child = ref)} />
<button onClick={this.onClick}>Child.method()</button>
</div>
);
}
}
Ссылка - https://github.com/kriasoft/react-starter-kit/issues/909#issuecomment-252969542
Ответ 4
Что если вам нужно управлять состоянием многих дочерних компонентов? Если мы сохраняем состояние в родительском элементе, это означает, что каждый дочерний элемент будет изменен, если состояние в родительском элементе будет изменено, верно? Как мы могли бы изменить в Что, если вам нужно управлять состоянием многих дочерних компонентов? Если мы сохраняем состояние в родительском элементе, это означает, что каждый дочерний элемент будет изменен, если состояние в родительском элементе будет изменено, верно? Как мы можем изменить в отдельных состояниях каждого компонента?
Ответ 5
Вы можете отправить реквизит из родительского элемента и использовать его в дочернем компоненте, поэтому вы будете основывать изменения дочернего состояния на отправленных изменениях реквизита, и вы можете справиться с этим, используя getDerivedStateFromProps в дочернем компоненте.