Javascript React js从父组件更改子组件的状态

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39041710/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 22:08:40  来源:igfitidea点击:

React js change child component's state from parent component

javascriptreactjs

提问by torayeff

I have two components: Parent Componentfrom which I want to change child component's state:

我有两个组件: 我想从中更改子组件状态的父组件

class ParentComponent extends Component {
  toggleChildMenu() {
    ?????????
  }
  render() {
    return (
      <div>
        <button onClick={toggleChildMenu.bind(this)}>
          Toggle Menu from Parent
        </button>
        <ChildComponent />
      </div>
    );
  }
}

And Child Component:

子组件

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}/>
    );
  }
}

I need to either change Child Component's openstate from Parent Component, or call Child Component's toggleMenu()from Parent Component when Button in Parent Component is clicked?

我需要从父组件更改子组件的打开状态,还是在单击父组件中的按钮时从父组件调用子组件的toggleMenu()

回答by Olivier Boissé

The state should be managed in the parent component. You can transfer the openvalue to the child component by adding a property.

状态应该在父组件中管理。您可以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}/>
      );
    }
}

回答by miguel savignano

The parent component can manage child state passing a prop to child and the child convert this prop in state using componentWillReceiveProps.

父组件可以管理将 prop 传递给子组件的子状态,子组件使用 componentWillReceiveProps 将这个 prop 转换为 state。

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} />
  }
}

回答by Jaison

Above answer is partially correct for me, but In my scenario, I want to set the value to a state, because I have used the value to show/toggle a modal. So I have used like below. Hope it will help someone.

上面的答案对我来说部分正确,但在我的场景中,我想将该值设置为一个状态,因为我已使用该值来显示/切换模态。所以我使用如下。希望它会帮助某人。

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>
    );
  }
}

Reference - https://github.com/kriasoft/react-starter-kit/issues/909#issuecomment-252969542

参考 - https://github.com/kriasoft/react-starter-kit/issues/909#issuecomment-252969542

回答by Juba Fourali

You can send a prop from the parent and use it in child component so you will base child's state changes on the sent prop changes and you can handle this by using getDerivedStateFromPropsin the child component.

您可以从父组件发送一个 prop 并在子组件中使用它,这样您就可以将子组件的状态更改基于发送的 prop 更改,并且您可以通过在子组件中使用getDerivedStateFromProps来处理此问题。

回答by Pranay kumar

You can use the createRef to change the state of the child component from the parent component. Here are all the steps.

您可以使用 createRef 从父组件更改子组件的状态。这是所有步骤。

  1. Create a method to change the state in the child component.

    2 - Create a reference for the child component in parent component using React.createRef().

    3 - Attach reference with the child component using ref={}.

    4 - Call the child component method using this.yor-reference.current.method.

  1. 创建一个方法来更改子组件中的状态。

    2 - 使用 React.createRef() 在父组件中为子组件创建引用。

    3 - 使用 ref={} 将引用附加到子组件。

    4 - 使用 this.yor-reference.current.method 调用子组件方法。

Parent component

父组件


class ParentComponent extends Component {
constructor()
{
this.changeChild=React.createRef()
}
  render() {
    return (
      <div>
        <button onClick={this.changeChild.current.toggleMenu()}>
          Toggle Menu from Parent
        </button>
        <ChildComponent ref={this.changeChild} />
      </div>
    );
  }
}

Child Component

子组件


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}/>
    );
  }
}