返回顶部
首页 > 资讯 > 前端开发 > JavaScript >React的组件协同使用实现方式
  • 816
分享到

React的组件协同使用实现方式

2024-04-02 19:04:59 816人浏览 泡泡鱼
摘要

目录嵌套父子组件通信兄弟组件通信抽离MixinReact的LinkedStateMixinReference:开发人员不用太过于关注UI层面的实现细节,考虑最多的也就是组件与组件之间

开发人员不用太过于关注UI层面的实现细节,考虑最多的也就是组件与组件之间的数据通信了。那么,在React开发中,有哪些场景的组件协同?又如何去实现组件的协同使用呢?

组件的协同本质上是对组件的一种组织、管理方式。

目的是使得系统 逻辑清晰、代码模块化、封装细节、代码可复用。

组件的协同分为两种方式:嵌套、抽离、发布订阅模式。

嵌套

组件嵌套的本质就是父子关系,即为父组件和子组件之间的通信。

总的来说有两种场景:

  • 父子组件通信
  • 兄弟组件通信

父子组件通信

首先我们先来看看最常用的一个手段,通过props属性。以父子组件为例,父组件只需要将数据以props的方式传递给子组件,子组件可以直接通过this.props来获取,比如:


// 父组件 Parent
export default class Parent extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      message: '传给子组件的消息'
    }
  }

  // 消息回调
  onMessage(messageFromChildren) {
    console.log(messageFromChildren);
  }

  render() {
    const { message } = this.state;
    return (
      <div>
        <Children message={ message } onMessage={ this.onMessage.bind(this) } />
      </div>
    );
  }
}

// 子组件 Children
export default class Children extends React.Component {
  constructor(props) {
    super(props);
  }

  handleClick() {
    this.props.onMessage('来自子组件的消息');
  }

  render() {
    const { message } = this.props;
    return (
      <div>
        <p>{ message }</p>
        <button onClick={ this.handleClick.bind(this) }>click</button>
      </div>
    );
  }
}

当然,如果Children子组件需要传递数据给到父组件,可以使用回调方式,父组件将方法的引用通过props传递给到子组件,如上代码中的handleClick里调用了onMessage。当父组件的state更新时,Children组件会重新渲染,使用最新的message数据。

bind的作用就是给函数增加默认的参数,第一个传参将替代方法里面的this

兄弟组件通信

兄弟组件不能直接相互通信,需要通过父组件来中转一下,进行状态提升。兄弟组件将需要共享的数据提升至共同的直接父组件中,然后就跟普通的父子组件通信一样了。比如:


// 父组件 Parent
export default class Parent extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      messageFromA: '',
      messageFromB: ''
    }
  }

  onMessage(messageFromChildren, from) {
    console.log(messageFromChildren);

    this.setState({
      [from == 'A' ? 'messageFromA' : 'messageFromB']: messageFromChildren
    });
  }

  render() {
    const { messageFromA,  messageFromB} = this.state;
    return (
      <div>
        <ChildrenA message={ messageFromB } onMessage={ this.onMessage.bind(this) } />
        <ChildrenB message={ messageFromA } onMessage={ this.onMessage.bind(this) } />
      </div>
    );
  }
}

// 子组件ChildrenA
export default class ChildrenA extends React.Component {
  constructor(props) {
    super(props);
  }

  handleClick() {
    this.props.onMessage('来自A子组件的消息', 'A');
  }

  render() {
    const { message } = this.props;
    return (
      <div className="p-a b-a">
        <p>{ message }</p>
        <button onClick={this.handleClick.bind(this)}>clickA</button>
      </div>
    );
  }
}

// 子组件 ChildrenB
export default class ChildrenB extends React.Component {
  constructor(props) {
    super(props);
  }

  handleClick() {
    this.props.onMessage('来自B子组件的消息', 'B');
  }

  render() {
    const { message } = this.props;
    return (
      <div className="p-a b-a">
        <p>{ message }</p>
        <button onClick={this.handleClick.bind(this)}>clickB</button>
      </div>
    );
  }
}

当点击clickA的时候,子组件B接收到了子组件A的消息,反之亦然。

通过props的组件通信比较简单,但也有其自身的缺陷,当组件层级大于3层时,这种方式就不适合了,首先是深层级的传递对到维护来说简直就是噩梦,需要一层一层的看才能知道数据的来源及流向。其次的话,假如不止A、B子组件,还有C子组件的,A、B组件引发的父组件state更新会触发C子组件的更新,但事实上,C子组件并没有接收任何数据,容易造成资源浪费。


// Parent组件
  render() {
    const { messageFromA,  messageFromB} = this.state;
    return (
      <div>
        <ChildrenA message={ messageFromB } onMessage={ this.onMessage.bind(this) } />
        <ChildrenB message={ messageFromA } onMessage={ this.onMessage.bind(this) } />
        <ChildrenC />
      </div>
    );
  }

// 子组件 ChildrenC
export default class ChildrenC extends React.Component {
  constructor(props) {
    super(props);
  }

  componentDidUpdate() {
    console.log('ChildrenC updated');
  }


  render() {
    return (
      <div>ChildrenC</div>
    );
  }
}

抽离

Mixin

这里要介绍的抽离主要是指Mixin。

假设有多个组件使用相同的getDefaultProps方法,我们就可以定义如下Mixin:


var DefaultNameMixin = {
    getDefaultProps: function () {
        return {name: "Tom"};
    }
};

Mixin相当于组件的一个扩展,它的本质就是一组方法的集合,使用这个 mixin 的组件能够自由的使用这些方法(就像在组件中定义的一样)。使用Mixin的目的就是横向抽离出组件的相似代码。

与Mixin思路相似的概念还有:aop插件

例子中,DefaultNameMixin中包含getDefaultProps方法。除了直接定义外,Mixin还可以嵌套使用,也就是可以在定义Mixin时使用另一个Mixin:


var DefaultCommonMixin = {
    mixins:[DefaultNameMixin], //use Mixin
    getDefaultProps: function () {
        return {food: "rice"};
    }
};

例子中,在DefaultCommonMixin的定义中嵌套使用了DefaultNameMixin,因此DefaultCommonMixin包含了DefaultNameMixin中定义的getDefaultProps方法,此时DefaultCommonMixin中有两个方法。使用Mixin时,只需将Mixin加入到mixins属性对应的数组中,Mixin的使用语法为mixins:[Mixin1,Mixin2……]。

使用Mixin时,只需将Mixin加入到mixins属性对应的数组中,Mixin的使用语法为mixins:[Mixin1,Mixin2……]。


var Component = React.createClass({
    mixins:[DefaultCommonMixin], //use Mixin
    render:function(){
        return <h1>{this.props.name} like {this.props.food}</h1>;
    }
}); 

ReactDOM.render(
    <Component/>,
    document.getElementById("example")
);

一个组件可以使用多个Mixin,同时,Mixin也可使用在多个组件中。

使用Mixin时,需要注意不要在多个地方设置相同的Prop和State。同时,在不同的Mixin中定义相同的方法,或者Mixin和组件中包含了相同的方法时,也会抛出异常,但是这种情况对componentDidMount等生命周期方法不适用(render方法除外,多次定义render方法也会抛出异常)。

如果在一个组件的多个地方定义了相同的生命周期方法,这些方法的执行顺序为:Mixin中的方法会优先执行(根据mixins中的顺序从左到右的顺序),然后执行组件中定义的方法。

Mixin的优点:

代码复用:抽离出通用代码,减少开发成本,提高开发效率

即插即用:可以直接使用许多现有的Mixin来编写自己的组件

适应性强:改动一次代码,影响多个组件

Mixin的缺点:

编写难度高:Mixin可能被用在各种环境中,兼容多种环境就需要更多的逻辑和代码,通用的代价是提高复杂度。

降低代码可读性:组件的优势在于将逻辑和界面直接结合在一起,Mixin本质上会分散逻辑,理解起来难度更大。

React的LinkedStateMixin


'use strict';  
  
// 构建对象{value,requestChange},value为初始值,requestChange为方法,须手动调用  
// 在本模块中,value为state[key]的初始值,requestChange用于更新state[key]  
var ReactLink = require('./ReactLink');  
  
// 设定属性key后,返回函数,该函数接受value,内部调用组件component.setState方法,更新state[key]=value  
var ReactStateSetters = require('./ReactStateSetters');  
  
  
var LinkedStateMixin = {  
  // ReactStateSetters.createStateKeySetter方法用于构建linkState(key)返回对象的requestChange方法  
  // 实现传值后自动调用setState方法,更新state  
  linkState: function (key) {  
    return new ReactLink(this.state[key], ReactStateSetters.createStateKeySetter(this, key));  
  }  
};  
  
module.exports = LinkedStateMixin;  

使用上述的Mixin:


import LinkedStateMixin from 'react-addons-linked-state-mixin'

mixins: [React.addons.LinkedStateMixin],

LinkedStateMixin仅仅是一个onChange/setState()模式的简单包装和约定。它不会从根本上改变数据在你的React应用中如何流动,也就是说其实LinkedStateMixin本质还是单向流,只是通过onChange将数据更改传递给React,然后内部数据改变就自动调用setState来进行更新。

使用示例:


var WithLink = React.createClass({
  mixins: [LinkedStateMixin],
  getInitialState: function() {
    return {message: 'Hello!'};
  },
  render: function() {
    return <input type="text" valueLink={this.linkState('message')} />;
  }
});

LinkedStateMixin给你的React组件添加一个叫做linkState()的方法。linkState()返回一个包含React state当前的值和用来改变它的回调函数的valueLink对象。

valueLink 对象可以在树中作为props被向上传递或者向下传递,所以它在组件层和状态层建立起双向绑定是非常简单的。

注意:

对于checkboxvalue属性,有一个特殊的行为,如果checkbox被选中(默认是on),value属性值将会在表单提交的时候发送出去。当checkbox被选中或者取消选中的时候,value属性是不会更新的。对于checkbox,你应该使用checkLink而不是valueLink

<checkbox type="checkbox" checkedLink={this.linkState('booleanValue')} />

Reference:

1. Http://schifred.iteye.com/blog/2361478

2. http://blog.csdn.net/qq_18661257/article/details/68951561

到此这篇关于React的组件协同使用的文章就介绍到这了,更多相关React组件协同内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: React的组件协同使用实现方式

本文链接: https://lsjlt.com/news/136113.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • React的组件协同使用实现方式
    目录嵌套父子组件通信兄弟组件通信抽离MixinReact的LinkedStateMixinReference:开发人员不用太过于关注UI层面的实现细节,考虑最多的也就是组件与组件之间...
    99+
    2024-04-02
  • React组件通信实现方式详解
    目录1. 父子组件通信方式父传子子传父2. 非父子组件通信方式1. 父子组件通信方式 ✨父子组件之间的通信很常见,其中父组件可以通过props,原型方法向子组件通信,同时子组件也可以...
    99+
    2023-03-19
    React组件通信 React通信 React组件通信的方式
  • Go并发:使用sync.WaitGroup实现协程同步方式
    经常看到有人会问如何等待主协程中创建的协程执行完毕之后再结束主协程,例如如下代码: package main import ( "fmt" ) func main()...
    99+
    2022-06-07
    GO sync 协程
  • 探讨如何使用不同的布局方式来实现Swiper组件
    随着移动设备的普及和用户对交互性体验的要求提高,轮播图已经成为了许多移动端应用和网站中的常见组件。在Uniapp中,Swiper组件可以帮助我们快速地实现轮播图功能。然而,Swiper默认的布局方式可能无法满足我们的需求,本文将探讨如何使用...
    99+
    2023-05-14
  • React中使用antd组件的方法
    目录antd使用antdantd antd 是基于 Ant Design 设计体系的 React UI 组件库,主要用于研发企业级中后台产品。 国内镜像为:https://ant-d...
    99+
    2024-04-02
  • 详解react hooks组件间的传值方式(使用ts)
    目录父传子子传父跨级组件(父传后代)父传子 通过props传值,使用useState来控制state的状态值 父组件 Father.tsx里: 子组件 Child.tsx里: ...
    99+
    2024-04-02
  • React函数式组件与类组件的不同你知道吗
    目录区别其他区别总结区别 区别函数组件类组件生命周期无有this无有state无有改变stateReact Hooks:useStatethis.setState()性能高(不用实例...
    99+
    2024-04-02
  • React函数式组件与类组件的不同点是什么
    本文小编为大家详细介绍“React函数式组件与类组件的不同点是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“React函数式组件与类组件的不同点是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。区别区别函...
    99+
    2023-06-29
  • 使用react怎么实现一个Radio组件
    使用react怎么实现一个Radio组件?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。测试组件:class Test extends Comp...
    99+
    2023-06-14
  • 怎么使用react实现一个tab组件
    本教程操作环境:windows7系统、react18.0.0版、Dell G3电脑。怎么使用react实现一个tab组件?react写Tab组件使用react写TAB栏组件和对应hover事件(背景:在用gatsby开发页面时,遇到这样的组...
    99+
    2022-11-22
    tab组件 React
  • 如何使用react实现一个tab组件
    这篇“如何使用react实现一个tab组件”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“如何使用react实现一个tab组件...
    99+
    2023-07-04
  • React父子组件传值(组件通信)的实现方法
    目录1、父组件传值子组件2、子组件传值父组件3、兄弟组件传值1、父组件传值子组件 在引用子组件的时候传递,相当于一个属性,例如:在子组件内通过porps.param获取到这个para...
    99+
    2024-04-02
  • React创建组件的的方式汇总
    目录1. 使用函数创建组件2. 使用类创建组件3. 抽离为独立JS文件1. 使用函数创建组件   函数组件:使用JS的函数(或箭头函数)创建的组件   约定1:函数名称必须以大写字母...
    99+
    2024-04-02
  • 使用 TypeScript 开发 React 函数式组件
    目录前言如何使用 TypeScript 定义函数式组件1. 使用 React.FC2. 使用 JSX.Element3. 直接定义完整类型4. 使用 React.PropsWithC...
    99+
    2024-04-02
  • react拖拽组件react-sortable-hoc的使用
    目录1.文件12.文件23.使用使用react-sortable-hoc实现拖拽 如图: 提示:下面案例可供参考 1.文件1 代码如下(示例):文件名称:./dragcompone...
    99+
    2023-02-24
    react拖拽组件 react sortable-hoc
  • React创建组件的方式有哪些
    这篇文章主要介绍了React创建组件的方式有哪些,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。React推出后,出于不同的原因先后出现三种定...
    99+
    2024-04-02
  • React实现组件全屏化的操作方法
    介绍 本文基于React+antd,给大家演示一个完整的全屏demo。 起因是开发今天给我提了一个sql编辑器输入框比较小,不支持放大,不太方便。希望能够全屏显示,联想到自己以后可能...
    99+
    2024-04-02
  • React组件创建与事件绑定的实现方法
    目录1、组件创建方式方式一-函数创建组件方式二-使用类创建组件2、事件绑定方式一-类组件绑定事件方式二-函数组件绑定事件周末在家,练习React,记录下来,方便查看。 本期学习Rea...
    99+
    2022-12-26
    React组件创建 React事件绑定
  • React实现动态调用的弹框组件
    最近在用react开发项目,遇到一个需求——开发一个弹框组件。在react中创建一个组件是很简单的,只需要使用class创建并引入就可以了,但是要做到可以用j...
    99+
    2024-04-02
  • HTTP 协议:Python 和 JavaScript 有哪些不同的实现方式?
    HTTP 协议是现代互联网通信的基础。Python 和 JavaScript 都有自己的实现方式,本文将会介绍它们之间的不同点和各自的优缺点。 Python 的 HTTP 实现方式 Python 提供了多种 HTTP 实现库,其中最常用的是...
    99+
    2023-08-30
    javascript unix http
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作