React js, alt bileşenin durumunu üst bileşenden değiştirir


101

İki bileşenim var: Alt bileşenin durumunu değiştirmek istediğim Üst Bileşen :

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

Ve Alt Bileşen :

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

Ya değişime Çocuk Component'ın gerek açık Veli Bileşeni veya çağrı Çocuk Component'ın gelen devlet toggleMenu () Veli Bileşen Button tıklandığında Veli Bileşen'den?


Belki ebeveyn bir çocuk referansını tutabilir ve değişiklik çocuğun devlet açıkça, bu Bkz doc
Chaojun Zhong

Yanıtlar:


125

Devlet, ana bileşende yönetilmelidir. openBir özellik ekleyerek değeri alt bileşene aktarabilirsiniz .

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

Bu, 'display' gibi bir css özelliğini kontrol etmek için kullanılabilir mi? 'open' prop'm 'none' veya 'inline-block' içeriyorsa, css display prop güncellenecek mi?
deusofnull

3
Evet, esasen react-classnames paketinin yaptığı şey budur, ancak aynı zamanda her zaman bir dizi sınıf adı uygulamanıza ve diğerlerini koşullu olarak uygulamanıza izin verir. Bunun gibi: classNames({ foo: true, bar: this.props.open });// => this.props.open = false olduğunda 'foo' ve this.props.open = true olduğunda 'foo bar'.
deusofnull

1
Alt bileşendeki açık durumu nasıl değiştirebiliriz?
Priyabrata Atha

1
toggleChildComponent'e bir özellik ekleyebilir ve alt bileşeni <ChildComponent open={this.state.open} toggle={this.toggleChildMenu.bind(this)} />arayabilirsinizthis.props.toggle()
Olivier Boissé

1
Anlamıyorum, ChildComponent-><ChildComponent toggle={this.toggleChildMenu.bind(this)} />
Olivier Boissé'yi

25

Üst bileşen, alt öğe durumunu alt öğeye geçirerek yönetebilir ve alt öğe, componentWillReceiveProps kullanarak bu pervaneyi duruma dönüştürür.

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
tepki 16'da getDerivedStateFromProps
Fadi Abo Msalam'ı

1
@FadiAboMsalam @ Types / react sürüm 16.7.18 ile react 16.7.0 sürümünü kullanıyorum. En azından TypeScript tarafında öyle görünmüyor getDerivedStateFromProps(). Bununla birlikte, Miguel'in kullanmayı öneren cevabı componentWillReceiveProps(props)mevcut ve ortamımda bir cazibe gibi çalıştı.
Manfred

Bu durumda, alt bileşenin içindeki toggleMenu () durumu değişikliği üst öğeye nasıl ulaşır? Çekmeceyi kapattığımı hayal edin, ana bileşen kapandığını nasıl anlar?
norman123123

20

Yukarıdaki cevap benim için kısmen doğru, ancak benim senaryomda, değeri bir duruma ayarlamak istiyorum, çünkü değeri bir modeli göstermek / değiştirmek için kullandım. Bu yüzden aşağıdaki gibi kullandım. Umarım birine yardımcı olur.

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

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


2
İstediğim bu, ama merak ediyorum neden sadece react refs kullanmıyorum? bkz. doc
Chaojun Zhong

OnRef prop ne yapar?
norman123123

2

Üst bileşenden alt bileşenin durumunu değiştirmek için createRef'i kullanabilirsiniz. İşte tüm adımlar.

  1. Alt bileşendeki durumu değiştirmek için bir yöntem oluşturun.

    2 - React.createRef () kullanarak üst bileşendeki alt bileşen için bir referans oluşturun.

    3 - ref = {} kullanarak alt bileşene referans ekleyin.

    4 - this.yor-reference.current.method'u kullanarak alt bileşen yöntemini çağırın.

Üst bileşen


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

Alt Bileşen


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

Üst öğeden bir prop gönderebilir ve onu alt bileşende kullanabilirsiniz, böylece alt bileşenin durum değişikliklerini gönderilen öznitelik değişikliklerine dayandırırsınız ve bunu alt bileşende getDerivedStateFromProps kullanarak halledebilirsiniz .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.