web-dev-qa-db-fra.com

React js change l'état du composant enfant du composant parent

J'ai deux composants: composant parent à partir duquel je veux changer l'état du composant enfant:

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

Et composante enfant:

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

Je dois soit changer l'état open du composant enfant du composant parent, soit appeler celui du composant enfant toggleMenu () du composant parent lorsque l'utilisateur clique sur Bouton dans le composant parent?

71
torayeff

L'état doit être géré dans le composant parent. Vous pouvez transférer la valeur open au composant enfant en ajoutant une propriété.

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}/>
      );
    }
}
102
Olivier Boissé

Le composant parent peut gérer l'état enfant en passant un accessoire à l'enfant et l'enfant convertit cet accessoire en état à l'aide de composantWillReceiveProps.

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} />
  }
}
16
miguel savignano

La réponse ci-dessus est partiellement correcte pour moi, mais dans mon scénario, je souhaite définir la valeur sur un état, car j'ai utilisé cette valeur pour afficher/basculer une modale. J'ai donc utilisé comme ci-dessous. J'espère que ça va aider quelqu'un.

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

Référence - https://github.com/kriasoft/react-starter-kit/issues/909#issuecomment-252969542

14
Jaison

Vous pouvez envoyer un accessoire à partir du parent et l'utiliser dans le composant enfant afin de baser les modifications d'état de l'enfant sur les modifications d'accesseur envoyées. Vous pouvez le gérer en utilisant getDerivedStateFromProps dans le composant enfant.

0
Juba FOURALI