React js thay đổi trạng thái của thành phần con từ thành phần mẹ


93

Tôi có hai thành phần: Thành phần chính mà từ đó tôi muốn thay đổi trạng thái của thành phần con:

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

thành phần con :

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

Tôi cần thay đổi trạng thái mở của Thành phần con từ Thành phần mẹ hoặc gọi toggleMenu () của Thành phần con từ Thành phần mẹ khi nhấp vào Nút trong Thành phần mẹ?


Có lẽ bạn có thể giữ một tham chiếu con ở phụ huynh, và tiểu bang thay đổi của con một cách rõ ràng, Xem này doc
Chaojun Zhong

Câu trả lời:


122

Trạng thái nên được quản lý trong thành phần mẹ. Bạn có thể chuyển opengiá trị cho thành phần con bằng cách thêm một thuộc tính.

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

Điều này có thể được sử dụng để kiểm soát một thuộc tính css như 'display' không? như trong, nếu phần mềm 'mở' của tôi chứa 'không có' hoặc 'khối nội tuyến', thì phần hỗ trợ hiển thị css có được cập nhật không?
deusofnull

2
Vâng, đó về cơ bản là những gì mà gói tên lớp phản ứng làm, nhưng nó cũng cho phép bạn luôn áp dụng một tập hợp các tên lớp và áp dụng những tên khác có điều kiện. Như thế này: classNames({ foo: true, bar: this.props.open });// => 'foo' khi this.props.open = false và 'foo bar' khi this.props.open = true.
deusofnull

1
Làm thế nào chúng ta có thể thay đổi trạng thái mở trong thành phần con?
Priyabrata Atha

1
bạn có thể thêm một thuộc tính togglevào ChildComponent <ChildComponent open={this.state.open} toggle={this.toggleChildMenu.bind(this)} />và gọi this.props.toggle()trong thành phần con
Olivier Boissé 02/02

1
Tôi không hiểu, bạn có thể gọi nó là bất cứ nơi nào bạn muốn trong thành phần con càng sớm càng tốt quy định tài sản này khi tuyên bố ChildComponent-><ChildComponent toggle={this.toggleChildMenu.bind(this)} />
Olivier Boisse

25

Thành phần cha có thể quản lý trạng thái con chuyển một hỗ trợ cho con và thành phần con chuyển đổi trạng thái hỗ trợ này bằng cách sử dụng 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
trong phản ứng 16 sử dụng getDerivedStateFromProps
Fadi Abo Msalam

1
@FadiAboMsalam Tôi đang sử dụng phiên bản phản ứng 16.7.0 với @ Loại / phiên bản phản ứng 16.7.18. Ít nhất ở phía TypeScript dường như không có getDerivedStateFromProps(). Tuy nhiên, câu trả lời đề nghị sử dụng của Miguel componentWillReceiveProps(props)có sẵn và hoạt động như một sự quyến rũ trong lòng tôi.
Manfred

Trong trường hợp này, trạng thái toggleMenu () thay đổi bên trong thành phần con sẽ đến với thành phần cha như thế nào? Hãy tưởng tượng tôi đóng ngăn kéo, làm thế nào để thành phần mẹ biết nó đã được đóng?
norman123123

20

Câu trả lời trên đúng với tôi một phần, nhưng trong trường hợp của tôi, tôi muốn đặt giá trị thành một trạng thái, vì tôi đã sử dụng giá trị để hiển thị / chuyển đổi một phương thức. Vì vậy, tôi đã sử dụng như dưới đây. Hy vọng nó sẽ giúp ích cho ai đó.

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

Tài liệu tham khảo - https://github.com/kriasoft/react-starter-kit/issues/909#issuecomment-252969542


2
Đây là những gì tôi muốn, nhưng tôi tự hỏi tại sao không chỉ sử dụng phản ứng refs? xem doc
Chaojun Zhong

Hỗ trợ onRef làm gì?
norman123123

1

Bạn có thể gửi một phần mềm hỗ trợ từ cha mẹ và sử dụng nó trong thành phần con để bạn sẽ thay đổi trạng thái của con dựa trên các thay đổi của phần tử con đã gửi và bạn có thể xử lý điều này bằng cách sử dụng getDerivedStateFromProps trong thành phần con.


1

Bạn có thể sử dụng createRef để thay đổi trạng thái của thành phần con từ thành phần mẹ. Đây là tất cả các bước.

  1. Tạo một phương thức để thay đổi trạng thái trong thành phần con.

    2 - Tạo một tham chiếu cho thành phần con trong thành phần mẹ bằng cách sử dụng React.createRef ().

    3 - Đính kèm tham chiếu với thành phần con bằng ref = {}.

    4 - Gọi phương thức thành phần con bằng this.yor-reference.current.method.

Thành phần chính


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

Thành phần con


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



Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.