• React 组件间通信介绍


    React 组件间通信方式简介


    React 组件间通信主要分为以下四种情况:

    • 父组件向子组件通信
    • 子组件向父组件通信
    • 跨级组件之间通信
    • 非嵌套组件间通信

    下面对这四种情况分别进行介绍:

     

    父组件向子组件通信

    父组件通过 props 和子组件进行通信,子组件得到 props 后进行相应的操作 
    父组件 App.js:

     
    1. import React, { Component } from 'react';
    2. import './App.css';
    3. import Child1 from './Child1';
    4. class App extends Component {
    5. render() {
    6. return (
    7. <div className="App">
    8. <Child1 content="父组件传递的内容" />
    9. </div>
    10. );
    11. }
    12. }
    13. export default App;

    子组件 Child1.jsx

     
    1. import React, { Component } from 'react';
    2. class Child1 extends Component {
    3. render () {
    4. return (
    5. <div>
    6. 子组件一:{ this.props.content }
    7. </div>
    8. )
    9. }
    10. }
    11. export default Child1;
     

    子组件向父组件通信

    和父组件向子组件通信类似,父组件通过传递 props 给子组件,只不过 props 的内容是一个函数,子组件通过调用父组件传递过来的回调函数,将子组件内容传递给父组件。 
    父组件 App.js

     
    1. import React, { Component } from 'react';
    2. import logo from './logo.svg';
    3. import './App.css';
    4. import Child1 from './Child1';
    5. import Child2 from './Child2';
    6. class App extends Component {
    7. constructor(){
    8. super();
    9. this.state = {
    10. msg:'',
    11. }
    12. }
    13. childMsg(msg){
    14. this.setState({
    15. msg: msg,
    16. })
    17. }
    18. render() {
    19. return (
    20. <div className="App">
    21. 子组件二传过来的内容:{this.state.msg}
    22. <Child2 childMsg={this.childMsg.bind(this)}/>
    23. </div>
    24. );
    25. }
    26. }
    27. export default App;

    子组件 Child2.jsx:

     
    1. import React, { Component } from 'react';
    2. class Child2 extends Component {
    3. msgHandle(){
    4. this.props.childMsg(this.refs.input.value);
    5. }
    6. render () {
    7. return (
    8. <div>
    9. 子组件二:
    10. <input type="text" placeholder='请输入内容' ref='input' />
    11. <button onClick={this.msgHandle.bind(this)}>点击向父组件传参</button>
    12. </div>
    13. )
    14. }
    15. }
    16. export default Child2;
     

    跨级组件通信

    跨级组件是指父组件向子组件的子组件进行通信,或者向更深层次的子组件通信,主要有两种方式:

    • 通过 props 层层传递
    • 使用 context 对象

    对于层级不深的组件(三层以内),可以使用 props 进行层层传递,如果说层级更深的话, 
    每一层组件都要去传递 props,并且这些 props 可能不是自身需要的,这就增加了复杂度,这种场景就可以使用 context 进行通信。context 是一个全局变量,相当于一个大容器,我们把要传递的信息放到这个容器里面,不管嵌套层级多深,子组件都可以获取到信息。使用 context 需要满足以下三个条件: 
    1、父组件需要声明自己支持 context,并提供 context 对象中属性的 PropTypes 
    2、子组件需要声明自己需要使用 context,并提供其需要使用的 context 属性的 PropTypes。 
    3、父组件需要提供一个 getChildContext 函数,用来返回一个初始的 context 对象

    props 层层传递: 
    父组件App.js:

     
    1. import React, { Component } from 'react';
    2. import logo from './logo.svg';
    3. import './App.css';
    4. import Child1 from './Child1';
    5. class App extends Component {
    6. constructor(){
    7. super();
    8. }
    9. render() {
    10. return (
    11. <div className="App">
    12. <Child1 content="父组件传递给孙子组件的内容" />
    13. </div>
    14. );
    15. }
    16. }
    17. export default App;

    Child1.jsx:

     
    1. import React, { Component } from 'react';
    2. import Child1_1 from './Child1_1';
    3. class Child1 extends Component {
    4. render () {
    5. return (
    6. <div>
    7. <Child1_1 content={this.props.content}/>
    8. </div>
    9. )
    10. }
    11. }
    12. export default Child1;

    Child1_1.jsx:

     
    1. import React, { Component } from 'react';
    2. class Child1_1 extends Component {
    3. render () {
    4. return (
    5. <div>
    6. 子组件一的子组件:{ this.props.content }
    7. </div>
    8. )
    9. }
    10. }
    11. export default Child1_1;

    context 对象传递 
    父组件App.js:

     
    1. import React, { Component } from 'react';
    2. import logo from './logo.svg';
    3. import './App.css';
    4. import PropTypes from "prop-types";
    5. import Child1 from './Child1';
    6. class App extends Component {
    7. // 声明支持 context
    8. static childContextTypes = {
    9. msgs: PropTypes.string,
    10. callBack: PropTypes.func,
    11. }
    12. // 父组件提供一个函数,返回初始的 context 对象
    13. getChildContext(){
    14. return {
    15. msgs:'父组件传递的初始内容',
    16. callBack:this.callBack
    17. }
    18. }
    19. callBack(msgs){
    20. console.log(msgs);
    21. }
    22. render() {
    23. return (
    24. <div className="App">
    25. <Child1 />
    26. </div>
    27. );
    28. }
    29. }
    30. export default App;

    子组件 Child1.jsx:

     
    1. import React, { Component } from 'react';
    2. import Child12 from './Child1_2';
    3. class Child1 extends Component {
    4. render () {
    5. return (
    6. <div>
    7. <Child12 />
    8. </div>
    9. )
    10. }
    11. }
    12. export default Child1;

    子组件的子组件 Child1_2:

     
    1. import React, { Component } from 'react';
    2. import PropTypes from 'prop-types';
    3. class Child1_2 extends Component {
    4. // 子组件声明需要调动 context
    5. static contextTypes = {
    6. msgs:PropTypes.string,
    7. callBack:PropTypes.func
    8. }
    9. callBack(){
    10. this.context.callBack('孙子组件的信息');
    11. }
    12. render () {
    13. return (
    14. <div>
    15. 子组件一的子组件:{ this.context.msgs }
    16. <button onClick={this.callBack.bind(this)}>点击给爷爷组件传递信息</button>
    17. </div>
    18. )
    19. }
    20. }
    21. export default Child1_2;
     

    非嵌套组件间通信

    表示没有任何包含关系的组件,主要包括兄弟组件和不在同一个父级中的非兄弟组件。

    • 使用共同父组件的 context 对象通信
    • 使用自定义事件的方式

    对于使用共同父组件 context 的方式会增加子组件和父组件之间的耦合度,对于层级较深的组件找到共同父组件也比较麻烦,但是这种方式可实施。

    为了避免父子组件之间的耦合度,我们采用自定义事件的方式: 
    需要安装 events 包,使用该模块的自定义事件机制npm i events --save 
    在根目录下新建 events.js 文件:

     
    1. import { EventEmitter } from 'events';
    2. export default new EventEmitter();

    父组件 App.js:

     
    1. import React, { Component } from 'react';
    2. import logo from './logo.svg';
    3. import './App.css';
    4. import Child1 from './Child1';
    5. import Child2 from './Child2';
    6. class App extends Component {
    7. render() {
    8. return (
    9. <div className="App">
    10. <Child1 />
    11. <Child2 />
    12. </div>
    13. );
    14. }
    15. }
    16. export default App;

    子组件 Child1.jsx:

     
    1. import React, { Component } from 'react';
    2. import emitter from './events';
    3. class Child1 extends Component {
    4. constructor(props){
    5. super(props);
    6. this.state = {
    7. msg:''
    8. }
    9. }
    10. // 组件挂载完后,声明一个自定义事件
    11. componentDidMount(){
    12. this.eventEmitter = emitter.addListener('selfEventName',msg => {
    13. this.setState({
    14. msg: msg
    15. })
    16. })
    17. }
    18. // 组件销毁前清除事件监听
    19. componentWillUnmount(){
    20. emitter.removeListener(this.eventEmitter)
    21. }
    22. render () {
    23. return (
    24. <div>
    25. 子组件二传递过来的内容:{ this.state.msg }
    26. </div>
    27. )
    28. }
    29. }
    30. export default Child1;

    子组件 Child2.jsx:

     
      1. import React, { Component } from 'react';
      2. import emitter from './events';
      3. class Child2 extends Component {
      4. msgHandle(){
      5. emitter.emit('selfEventName','自定义事件传参');
      6. }
      7. render () {
      8. return (
      9. <div>
      10. 子组件二:
      11. <button onClick={this.msgHandle.bind(this)}>点击向父组件传参</button>
      12. </div>
      13. )
      14. }
      15. }
      16. export default Child2;
  • 相关阅读:
    秒杀系统性能测试和优化
    性能测试分析过程(三)linux下查看最消耗CPU/内存的进程
    [改善Java代码]注意方法中传递的参数要求(replaceAll和replace的区别)
    [改善Java代码]由点及面,一叶知秋----集合大家族
    [改善Java代码]非稳定排序推荐使用List
    [改善Java代码]多线程使用Vector或HashTable
    [改善Java代码]减少HashMap中元素的数量
    [改善Java代码]使用shuffle打乱列表
    [改善Java代码]集合运算时使用更优雅的方式
    [改善Java代码]集合中的元素必须做到compareTo和equals同步
  • 原文地址:https://www.cnblogs.com/web-panpan/p/10486395.html
Copyright © 2020-2023  润新知