React js mengubah status komponen anak dari komponen induk


100

Saya memiliki dua komponen: Komponen Induk tempat saya ingin mengubah status komponen anak:

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

Dan Komponen Anak :

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

Saya perlu mengubah status terbuka Komponen Anak dari Komponen Induk, atau memanggil toggleMenu () Komponen Anak dari Komponen Induk saat Tombol di Komponen Induk diklik?


Mungkin Anda dapat mengadakan referensi anak sebagai orang tua, dan mengubah status anak secara eksplisit, Lihat dokumen
Chaojun Zhong

Jawaban:


125

Status harus dikelola di komponen induk. Anda dapat mentransfer opennilai ke komponen anak dengan menambahkan properti.

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

Bisakah ini digunakan untuk mengontrol properti css seperti 'display'? seperti pada, jika prop saya 'open' berisi 'none' atau 'inline-block', apakah prop tampilan css akan diperbarui?
deusofnull

3
Ya, pada dasarnya itulah yang dilakukan oleh paket react-classnames, tetapi juga memungkinkan Anda untuk selalu menerapkan satu set nama kelas, dan menerapkan yang lain secara bersyarat. Seperti ini: classNames({ foo: true, bar: this.props.open });// => 'foo' when this.props.open = false dan 'foo bar' when this.props.open = true.
deusofnull

1
Bagaimana kita bisa mengubah keadaan terbuka di komponen anak?
Priyabrata Atha

1
Anda dapat menambahkan properti toggleke ChildComponent <ChildComponent open={this.state.open} toggle={this.toggleChildMenu.bind(this)} />dan memanggil this.props.toggle()komponen anak
Olivier Boissé

1
Saya tidak mengerti, Anda dapat memanggilnya di mana pun Anda inginkan dalam komponen anak segera setelah Anda menentukan properti ini saat mendeklarasikan ChildComponent-><ChildComponent toggle={this.toggleChildMenu.bind(this)} />
Olivier Boissé

25

Komponen induk dapat mengelola status anak dengan meneruskan prop ke anak dan anak mengonversi prop ini dalam keadaan menggunakan 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} />
  }
}

1
dalam bereaksi 16 menggunakan getDerivedStateFromProps
Fadi Abo Msalam

1
@FadiAboMsalam Saya menggunakan react versi 16.7.0 dengan @ Type / react versi 16.7.18. Setidaknya di sisi TypeScript sepertinya tidak ada getDerivedStateFromProps(). Namun, jawaban Miguel yang menyarankan untuk menggunakan componentWillReceiveProps(props)tersedia dan bekerja seperti pesona di env saya.
Manfred

Dalam kasus ini, bagaimana status toggleMenu () berubah di dalam komponen anak akan mencapai induknya? Bayangkan saya menutup laci, bagaimana komponen induk mengetahui bahwa laci telah ditutup?
norman123123

20

Jawaban di atas sebagian benar untuk saya, tetapi dalam skenario saya, saya ingin menetapkan nilai ke status, karena saya telah menggunakan nilai untuk menampilkan / mengalihkan modal. Jadi saya telah menggunakan seperti di bawah ini. Semoga bisa membantu seseorang.

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

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


2
Ini yang saya inginkan, tapi saya bertanya-tanya mengapa tidak menggunakan react refs? lihat dok
Chaojun Zhong

Apa yang dilakukan prop onRef?
norman123123

2

Anda dapat menggunakan createRef untuk mengubah status komponen anak dari komponen induk. Ini semua langkahnya.

  1. Buat metode untuk mengubah status di komponen anak.

    2 - Buat referensi untuk komponen anak dalam komponen induk menggunakan React.createRef ().

    3 - Lampirkan referensi dengan komponen anak menggunakan ref = {}.

    4 - Panggil metode komponen anak menggunakan this.yor-reference.current.method.

Komponen induk


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

Komponen Anak


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




1

Anda dapat mengirim prop dari induk dan menggunakannya dalam komponen anak sehingga Anda akan mendasarkan perubahan status anak pada perubahan prop yang dikirim dan Anda dapat menangani ini dengan menggunakan getDerivedStateFromProps di komponen anak.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.