返回

突破框架,畅享自由:React组件通信方式大解析

前端

我们知道,React组件通信方式有很多种,在项目开发中,我们需要根据:项目复杂程度、业务具体功能、以及组件层级关系,去灵活选择合适的通信方式。本文将简述下父子组件和兄弟组件通信的常用方式。

父子组件通信

父子组件通信是最常见的一种组件通信方式,可以通过以下几种方式实现:

Props: Props是最直接的父子组件通信方式,父组件通过Props将数据传递给子组件。

class ParentComponent extends React.Component {
  render() {
    return (
      <ChildComponent name="John" age={25} />
    );
  }
}

class ChildComponent extends React.Component {
  render() {
    return (
      <h1>Hello, {this.props.name}! You are {this.props.age} years old.</h1>
    );
  }
}

Context: Context是一种全局状态管理机制,可以跨组件传递数据。

const ThemeContext = React.createContext();

class ParentComponent extends React.Component {
  render() {
    return (
      <ThemeContext.Provider value="dark">
        <ChildComponent />
      </ThemeContext.Provider>
    );
  }
}

class ChildComponent extends React.Component {
  render() {
    const theme = React.useContext(ThemeContext);

    return (
      <div className={theme}>
        <h1>Hello, World!</h1>
      </div>
    );
  }
}

Redux: Redux是一个第三方状态管理库,可以实现父子组件之间的通信,也可以实现组件之间的通信。

const store = Redux.createStore(reducer);

class ParentComponent extends React.Component {
  render() {
    return (
      <Provider store={store}>
        <ChildComponent />
      </Provider>
    );
  }
}

class ChildComponent extends React.Component {
  componentDidMount() {
    this.unsubscribe = store.subscribe(() => this.forceUpdate());
  }

  componentWillUnmount() {
    this.unsubscribe();
  }

  render() {
    const state = store.getState();

    return (
      <div>
        <h1>Hello, World!</h1>
        <p>Count: {state.count}</p>
      </div>
    );
  }
}

兄弟组件通信

兄弟组件通信是指不具有父子关系的组件之间的通信,可以通过以下几种方式实现:

Props: Props也可以用于兄弟组件通信,但需要通过父组件传递数据。

class ParentComponent extends React.Component {
  render() {
    return (
      <>
        <ChildComponent1 name="John" />
        <ChildComponent2 name="Mary" />
      </>
    );
  }
}

class ChildComponent1 extends React.Component {
  render() {
    return (
      <h1>Hello, {this.props.name}!</h1>
    );
  }
}

class ChildComponent2 extends React.Component {
  render() {
    return (
      <h1>Hello, {this.props.name}!</h1>
    );
  }
}

Context: Context也可以用于兄弟组件通信,但需要在公共祖先组件中定义Context。

const ThemeContext = React.createContext();

class ParentComponent extends React.Component {
  render() {
    return (
      <ThemeContext.Provider value="dark">
        <ChildComponent1 />
        <ChildComponent2 />
      </ThemeContext.Provider>
    );
  }
}

class ChildComponent1 extends React.Component {
  render() {
    const theme = React.useContext(ThemeContext);

    return (
      <div className={theme}>
        <h1>Hello, World!</h1>
      </div>
    );
  }
}

class ChildComponent2 extends React.Component {
  render() {
    const theme = React.useContext(ThemeContext);

    return (
      <div className={theme}>
        <h1>Hello, World!</h1>
      </div>
    );
  }
}

Redux: Redux也可以用于兄弟组件通信,但需要在公共祖先组件中使用Provider组件。

const store = Redux.createStore(reducer);

class ParentComponent extends React.Component {
  render() {
    return (
      <Provider store={store}>
        <ChildComponent1 />
        <ChildComponent2 />
      </Provider>
    );
  }
}

class ChildComponent1 extends React.Component {
  componentDidMount() {
    this.unsubscribe = store.subscribe(() => this.forceUpdate());
  }

  componentWillUnmount() {
    this.unsubscribe();
  }

  render() {
    const state = store.getState();

    return (
      <div>
        <h1>Hello, World!</h1>
        <p>Count: {state.count}</p>
      </div>
    );
  }
}

class ChildComponent2 extends React.Component {
  componentDidMount() {
    this.unsubscribe = store.subscribe(() => this.forceUpdate());
  }

  componentWillUnmount() {
    this.unsubscribe();
  }

  render() {
    const state = store.getState();

    return (
      <div>
        <h1>Hello, World!</h1>
        <p>Count: {state.count}</p>
      </div>
    );
  }
}

PubSub-JS: PubSub-JS是一个第三方库,可以实现组件之间的事件通信。

const pubsub = PubSubJS();

class ChildComponent1 extends React.Component {
  componentDidMount() {
    pubsub.subscribe("eventName", (msg, data) => {
      // Handle the event
    });
  }

  componentWillUnmount() {
    pubsub.unsubscribe("eventName");
  }

  render() {
    return (
      <button onClick={() => pubsub.publish("eventName", { message: "Hello, World!" })}>
        Send Event
      </button>
    );
  }
}

class ChildComponent2 extends React.Component {
  componentDidMount() {
    pubsub.subscribe("eventName", (msg, data) => {
      // Handle the event
    });
  }

  componentWillUnmount() {
    pubsub.unsubscribe("eventName");
  }

  render() {
    return (
      <div>
        <h1>Hello, World!</h1>
      </div>
    );
  }
}

中间人组件: 中间人组件是指在两个兄弟组件之间建立通信桥梁的组件。

class ParentComponent extends React.Component {
  state = {
    data: null,
  };

  componentDidMount() {
    this.setState({ data: "Hello, World!" });
  }

  render() {
    return (
      <>
        <ChildComponent1 data={this.state.data} />
        <ChildComponent2 data={this.state.data} />
      </>
    );
  }
}

class ChildComponent1 extends React.Component {
  render() {
    return (
      <h1>{this.props.data}</h1>
    );
  }
}

class ChildComponent2 extends React.Component {
  render() {
    return (
      <h1>{this.props.data}</h1>
    );
  }
}

上述只是React组件通信方式的几种常见方式,还有许多其他的方式可以实现组件之间的通信,开发者可以根据具体的需求选择合适的通信方式。