如何使React组件与另一个React组件“通信”?

时间:2018-03-14 10:58:58

标签: reactjs jsx

我有一个父jsx组件,其中包含2个不同的jsx组件。 一个组件是一个按钮,另一个组件是一个div,当你点击它时它会自动打开和关闭它(它有一个点击处理程序和一个打开或关闭的状态)。 我现在想要添加按钮的功能来打开和关闭div。 完成此操作的唯一方法是将处理函数向下传递给父级的按钮,将div的打开和关闭状态移动到父组件,并将状态作为props传递给div?我问的原因是这个特定的div组件用在许多不同的组件中,删除open和closed状态会影响很多不同的父组件。

2 个答案:

答案 0 :(得分:1)

这是一个允许外部状态操作的代码示例,您可以混合使用按钮或div来切换状态。扩展可折叠组件以使用传递的props来更新状态。

class Collapsible extends React.Component {
  constructor(props){
    super(props);
    this.state = { isOpen: this.props.isOpen !== false };
    this.toggleOpen = this.toggleOpen.bind(this);
  }
  componentWillReceiveProps({ isOpen }) {
    this.setState({ isOpen });
  }
  toggleOpen(){
   this.setState((prevState) => ({ isOpen: !prevState.isOpen }))
  }
  render() {
    let display = this.state.isOpen ? null : "none";
    return (
      <div
        className="collapsible"
        onClick={this.toggleOpen}
      >
        <header> header </header>
        <div style={{ display }}>{this.props.children}</div>
      </div>
    );
  }
}

class Parent extends React.Component {
  constructor(props){
    super(props);
    this.state = { isOpen: true };
    this.toggleOpen = this.toggleOpen.bind(this);
  }

  toggleOpen(){
   this.setState((prevState) => ({ isOpen: !prevState.isOpen }))
  }

  render() {
    return (
      <div className="parent">
        <Collapsible isOpen={this.state.isOpen}>content</Collapsible>
        <button onClick={this.toggleOpen}>
          toggle
        </button>
      </div>
    );
  }
}

答案 1 :(得分:0)

这是另一个代码示例,希望它有所帮助:

Edit 3xrw9vny8m

我使用Container的本地状态并将其传递给子组件。在一个更大的应用程序中,我建议你使用像Redux之类的东西来管理你的状态。

中心思想是父组件将一个可以“改变它的状态”的函数传递给按钮子元素。它还将当前isOpen状态传递给面板。单击该按钮将更改父级的状态,从而触发重排,从而更新可折叠。

供将来参考:

import React from "react";
import { render } from "react-dom";

const Collapsable = ({ isOpen }) =>
  isOpen ? (
    <div
      style={{
        border: "1px solid orange",
        padding: "1rem",
        background: "maroon",
        color: "white"
      }}
    >
      {" "}
      Hey, I'm open{" "}
    </div>
  ) : (
    <div>Oh no...closed :(</div>
  );

const Button = ({ openPanel }) => (
  <button onClick={() => openPanel()}>Open Panel</button>
);

class Container extends React.PureComponent {
  state = { open: false };

  openPanel = () => {
    this.setState({
      ...this.state,
      open: this.state.open ? false : true
    });
  };

  render() {
    return (
      <div>
        <Button openPanel={this.openPanel} />
        <Collapsable isOpen={this.state.open} />
      </div>
    );
  }
}

const App = () => (
  <div>
    <Container />
  </div>
);

render(<App />, document.getElementById("root"));