返回顶部
首页 > 资讯 > 前端开发 > node.js >怎么在React中做到jQuery-free
  • 912
分享到

怎么在React中做到jQuery-free

2024-04-02 19:04:59 912人浏览 安东尼
摘要

这篇文章主要介绍怎么在React中做到Jquery-free,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!前言首先我们仍要说的是,jQuery 是现在***的 javascript

这篇文章主要介绍怎么在React中做到Jquery-free,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

前言

首先我们仍要说的是,jQuery 是现在***的 javascript 工具库。在 W3techs 的统计中,目前全世界 70.6% 的网站在使用他,而  React 甚至还不到 0.1%,但 React 一个值得注意的趋势是,他在目前***流量网站中的使用率是***的,比例达到了  16%。这一趋势也表明了目前整个前端界的技术趋势,但 70.6% 的数字也在告诉我们,jQuery 在 js  库中的王者地位,即使使用了React,也可能因为各种各样的原因,还要和 jQuery 来配合使用。但 React  本身的体积已经让我们对任何一个重库产生了不适反应,为了兼容 IE8,我们仍然需要使用 1.x 的 jQuery 版本,但当时设计上的缺陷使得我们无法像  lodash 那样按需获取。而 React 和 jsx 的强大,又使得我们不需要了 jQuery  的大部分功能。从这个角度来看,他臃肿的体积让开发者更加难以忍受,jQuery-free 势在必行。

一、选取 DOM 元素

在 jQuery 中,我们已经熟悉了使用 sizzle 选择器来完成 DOM 元素的选取。而在 React 中,我们可以使用 ref  来更有针对性的获取元素。

import React from 'react'; class Demo extends React.Compoent {      getDomnode() {         return this.refs.root; // 获取 Dom Node     }     render() {         return (             <div ref="root">just a demo</div>         );     } }

这是最简单的获取 node 的方式,如果有多层结构嵌套呢?没有关系。

import React from 'react'; class Demo extends React.Compoent {      getRootNode() {         return this.refs.root; // 获取根节点 Dom Node     }     getLeafNode() {         return this.refs.leaf; // 获取叶节点 Dom Node     }     render() {         return (             <div ref="root">                 <div ref="leaf">just a demo</div>             </div>         );     } }

如果是组件和组件嵌套呢?也没关系,父组件仍然可以拿到子组件的根节点。

import React from 'react'; import ReactDOM from 'react-dom'; class Sub extends React.Compoent {     render() {         return (             <div>a sub component</div>         );     } } class Demo extends React.Compoent {      getDomNode() {         return this.refs.root; // 获取 Dom Node     }          getSubNode() {         return ReactDOM.findDOMNode(this.refs.sub); // 获取子组件根节点     }     render() {         return (             <div ref="root">                 <Sub ref="sub" />             </div>         );     } }

上面使用了比较易懂的 api 来解释 Ref 的用法,但里面包含了一些现在 React 不太推荐和即将废弃的方法,如果用 React  推荐的写法,我们可以这样写。

import React from 'react'; import ReactDOM from 'react-dom'; class Sub extends React.Compoent {     getDomNode() {         return this.rootNode;     }     render() {         return (             <div ref={(c) => this.rootNode = c}>a sub component</div>         );     } } class Demo extends React.Compoent {      getDomNode() {         return this.rootNode; // 获取 Dom Node     }          getSubNode() {         return this.sub.getDomNode(); // 获取子组件根节点     }     render() {         return (             <div ref={(c) => this.rootNode = c}>                 <Sub ref={(c) => this.sub = c} />             </div>         );     } }

有人可能会问,那子组件怎么拿父组件的 Dom Node 呢,从 React  的单向数据流角度出发,遇到这种情况我们应该通过回调通知给父组件,再由父组件自行判断如何修改 Node,其实父组件拿子组件的 Node  情况也很少,大多数情况下我们是通过 props 传递变化给子组件,获取子组件 Node,更多的情况下是为了避开大量重新渲染去修改一些Node的属性(比如  scrollLeft)。

二、DOM 操作

jQuery 中提供了丰富的操作方法,但一个个操作 DOM 元素有的时候真的很烦人并且容易出错。React 通过数据驱动的思想,通过改变 view  对应的数据,轻松实现 DOM 的增删操作。

class Demo extends React.Compoent {     constructor(props) {         super(props);         this.state = {             list: [1, 2, 3],         };         this.addItemFromBottom = this.addItemFromBottom.bind(this);         this.addItemFromTop = this.addItemFromTop.bind(this);         this.deleteItem = this.deleteItem.bind(this);     }          addItemFromBottom() {         this.setState({             list: this.state.list.concat([4]),         });     }          addItemFromTop() {         this.setState({             list: [0].concat(this.state.list),         });     }          deleteItem() {         const newList = [...this.state.list];         newList.pop();         this.setState({             list: newList,         });     }          render() {         return (             <div>                 {this.state.list.map((item) => <div>{item}</div>)}                 <button onClick={this.addItemFromBottom}>尾部插入 Dom 元素</button>                 <button onClick={this.addItemFromTop}>头部插入 Dom 元素</button>                 <button onClick={this.deleteItem}>删除 Dom 元素</button>             </div>         );     } }

三、事件的监听

React 通过根节点代理的方式,实现了一套很优雅的事件监听方案,在组件 unmount 时也不需要自己去处理内存回收相关的问题,非常的方便。

import React from 'react'; class Demo extends React.Component {     constructor(props) {         super(props);         this.handleClick = this.handleClick.bind(this);     }     handleClick() {         alert('我是弹窗');     }     render() {         return (             <div onClick={this.handleClick}>点击我弹出弹框</div>         );     } }

这里有一个小细节就是 bind 的时机,bind 是为了保持相应函数的上下文,虽然也可以在 onClick 那里 bind,但这里选择在  constructor 里 bind 是因为前者会在每次 render 的时候都进行一次 bind,返回一个新函数,是比较消耗性能的做法。

但 React 的事件监听,毕竟只能监听至 root component,而我们在很多时候要去监听 window/document 上的事件,如果  resize、scroll,还有一些 React 处理不好的事件,比如  scroll,这些都需要我们自己来解决。事件监听为了屏蔽差异性需要做很多的工作,这里像大家推荐一个第三方库来完成这部分的工作,add-dom-event-listener,用法和原生的稍有区别,是因为这个库并不旨在做  polyfill,但用法还是很简单。

var addEventListener = require('add-dom-event-listener'); var handler = addEventListener(document.body, 'click', function(e){   console.log(e.target); // works for ie   console.log(e.nativeEvent); // native dom event }); handler.remove(); // detach event listener

另一个选择是 bean,达到了 IE6+ 级别的兼容性。

四、事件的触发

和事件监听一样,无论是 Dom 事件还是自定义事件,都有很优秀的第三方库帮我们去处理,如果是 DOM 事件,推荐 bean,如果是自定义事件的话,推荐  PubSubJS。

五、document.ready

React 作为一个 view 层框架,通常情况下页面只有一个用于渲染 React 页面组件的根节点 div,因此  document.ready,只需把脚本放在这个 div 后面执行即可。而对于渲染完成后的回调,我们可以使用 React 提供的  componentDidMount 生命周期。

import React from 'react'; class Demo extends React.Component {     constructor(props) {         super(props);     }          componentDidMount() {         doSomethingAfterRender(); // 在组件渲染完成后执行一些操作,如远程获取数据,检测 DOM 变化等。     }     render() {         return (             <div>just a demo</div>         );     } }

六、attr 方法

jQuery 使用 attr 方法,获取 Dom 元素的属性。在 React 中也可以配合 Ref 直接读取 DOM 元素的属性。

import React from 'react'; class Demo extends React.Component {     constructor(props) {         super(props);     }          componentDidMount() {         this.rootNode.scrollLeft = 10; // 渲染后将外层的滚动调至 10px     }     render() {         return (             <div                  ref={(c) => this.rootNode = c}                  style={{ width: '100px', overflow: 'auto' }}             >                  <div style={{ width: '1000px' }}>just a demo</div>             </div>         );     } }

但是,在大部分的情况下,我们完全不需要做,因为 React 的单向数据流和数据驱动渲染,我们可以不通过 DOM,轻松拿到和修改大部分我们需要的 DOM  属性。

import React from 'react'; class Demo extends React.Component {     constructor(props) {         super(props);         this.state = {             link: '//www.taobao.com',         };         this.getLink = this.getLink.bind(this);         this.editLink = this.editLink.bind(this);     }          getLink() {         alert(this.state.link);     }          editLink() {         this.setState({             link: '//www.tmall.com',         });     }          render() {         return (             <div>                 <a href={this.state.link}>跳转链接</a>                 <button onClick={this.getLink}>获取链接</button>                 <button onClick={this.editLink}>修改链接</button>             </div>         );     }      }

七、addClass/removeClass/toggleClass

在 jQuery 的时代,我们通常靠获取 Dom 元素后,再 addClass/removeClass 来改变外观。在 React  中通过数据驱动和第三库classnames 修改样式从未如此轻松。

.fn-show {     display: block; } .fn-hide {     display: none; }
import React from 'react'; import classnames from 'classnames'; class Demo extends React.Component {     constructor(props) {         super(props);         this.state = {             show: true,         };         this.changeShow = this.changeShow.bind(this);     }          changeShow() {         this.setState({             show: !this.state.show,          });     }          render() {         return (             <div>                 <a                      href="//www.taobao.com"                      className={classnames({                         'fn-show': this.state.show,                         'fn-hide': !this.state.show,                     })}                 >                     跳转链接                 </a>                 <button onClick={this.changeShow}>改变现实状态</button>             </div>         );     }      }

八、css

jQuery 的 CSS 方法用于设置 DOM 元素的 style 属性,在 React 中,我们可以直接设置 DOM 的 style  属性,如果想改变,和上面的 class 一样,用数据去驱动。

import React from 'react'; class Demo extends React.Component {     constructor() {         super(props);         this.state = {             backGorund: 'white',         };         this.handleClick = this.handleClick.bind(this);     }          handleClick() {         this.setState({             background: 'black',         });     }          render() {         return (             <div                  style={{                     background: this.state.background,                 }}             >                 just a demo                 <button>change Background Color</button>             </div>         );     } }

九、数据存储

比起 jQuery,React 反而是更擅长管理数据,我们没有必要像 jQuery 时那样将数据放进 Dom 元素的属性里,而是利用 state 或者  内部变量(this.xxx) 来保存,在整个生命周期,我们都可以拿到这些数据进行比较和修改。

十、Ajax

ajax 确实是在处理兼容性问题上一块令人比较头疼的地方,要兼容各种形式的 Xhr 不说,还有 JSONp 这个不属于 ajax  的功能也要同时考虑,好在已经有了很好的第三方库帮我们解决了这个问题,这里向大家推荐 natty-fetch,一个兼容 IE8 的fetch 库,在 API  设计上向 fetch 标准靠近,而又保留了和 jQuery 类似的接口,熟悉 $.ajax 应该可以很快的上手。

十一、动画

React 在动画方面提供了一个插件 ReactCSSTransitionGroup,和它的低级版本  ReactTransitionGroup,注意这里的低级并不是退化版本,而是更加基础的暴露更多 API 的版本。

这个插件的灵感来自于 angular 的 ng-animate,在设计思路上也基本保持一致。通过指定 Transition 的类名,比如 example  ,在元素进场和退场的时候分别加上对应的类名,以实现 css3 动画。例如本例中,进场会添加 example-enter 和  example-enter-active到对应的元素 ,而在退场 example-leave 和 example-leave-active  类名。当然你也可以指定不同的进场退场类名。而对应入场,React 也区分了两种类型,一种是 ReactCSSTransitionGroup  ***次渲染时(appear),而另一种是 ReactCSSTransitionGroup 已经渲染完成后,有新的元素插入进来(enter),这两种进场可以使用  prop 进行单独配置,禁止或者修改超时时长。具体的例子,在上面给出的链接中有详细的例子和说明,因此本文不再赘述。

但这个插件最多只提供了做动画的方案,如果我想在动画进行的过程中做一些其他事情呢?他就无能为力了,这时候就轮到 ReactTransitionGroup  出场了。ReactTransitionGroup 为他包裹的动画元素提供了六种新的生命周期:componentWillAppear(callback),  componentDidAppear(), componentWillEnter(callback),  componentDidEnter(),componentWillLeave(callback), componentDidLeave()。这些 hook  可以帮助我们完成一些随着动画进行需要做的其他事。

但官方提供的插件有一个不足点,动画只是在进场和出场时进行的,如果我的组件不是  mount/unmount,而只是隐藏和显示怎么办?这里推荐一个第三方库:rc-animate,从 API 设计上他基本上是延续了  ReactCSSTransitionGroup 的思路,但是通过引入 showProp这一属性,使他可以 handle  组件显示隐藏这一情况下的出入场动画(只要将组件关于 show/hide 的属性传给 showProp 即可),同时这个库也提供自己的 hook,来实现  appear/enter/leave 时的回调。

如果你说我并不满足只是进场和出场动画,我要实现类似鼠标拖动时的实时动画,我需要的是一个 js 动画库,这里向大家推荐一个第三方库:react-motion  , react-motion  一个很大的特点是,有别以往使用贝塞尔曲线来定义动画节奏,引入了刚度和阻尼这些弹簧系数来定义动画,按照作者的说法,与其纠结动画时长和很难掌握的贝塞尔表示法,通过不断调整刚度和阻尼来调试出最想要的弹性效果才是最合理的。Readme  里提供了一系列的很炫的动画效果,比如这个 draggable list。Motion 通过指定 defaultStyle、style,传回给子组件正在变化中的  style,从而实现 js 动画。

<Motion defaultStyle={{x: 0}} style={{x: spring(10)}}>   {interpolatingStyle => <div style={interpolatingStyle} />} </Motion>

以上是“怎么在React中做到jQuery-free”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注编程网node.js频道!

--结束END--

本文标题: 怎么在React中做到jQuery-free

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

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

猜你喜欢
  • 怎么在React中做到jQuery-free
    这篇文章主要介绍怎么在React中做到jQuery-free,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!前言首先我们仍要说的是,jQuery 是现在***的 JavaScript ...
    99+
    2024-04-02
  • 怎么在Linux中使用free命令
    今天就跟大家聊聊有关怎么在Linux中使用free命令,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。           ...
    99+
    2023-06-13
  • free命令怎么在linux中使用
    free命令怎么在linux中使用?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。命  令: free 功能说明:显示内存状态。 语  法: free [-bkmotV][-...
    99+
    2023-06-13
  • java中free怎么使用
    在Java中,没有直接使用`free()`方法来释放内存。Java采用了垃圾回收机制,通过自动管理内存的方式来释放不再使用的对象占用...
    99+
    2023-09-27
    java
  • c语言中free怎么用
    free() 函数释放动态分配的内存。其使用方法为:free(ptr),其中 ptr 是指向已分配内存的指针。使用时机是在不再需要由 malloc() 或 calloc() 分配的内存时...
    99+
    2024-05-10
    c语言 标准库
  • React中useCallbackuseMemo到底该怎么用
    目录useCallback记忆函数前言介绍使用useMemo记忆组件两者区别使用useCallback记忆函数 前言 使用缘由: 防止因为组件重新渲染,导致方法被重新创建,起到缓存作...
    99+
    2023-02-06
    React useCallback React useMemo
  • React中的useEffectuseLayoutEffect到底怎么用
    目录前言介绍使用空依赖非空依赖实现销毁操作两者区别前言 使用缘由: 在函数中当请求数据时并且给state赋值会导致整个函数刷新, 从而导致死循环的进行数据请求, 所以这时候可以用到u...
    99+
    2023-02-06
    React useEffect React useLayoutEffect
  • redux在react中怎么用
    这篇文章主要介绍redux在react中怎么用,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Redux是一个数据状态管理插件,当使用React或是vue开发组件化的SPA程序时,组件之间共享信息是一个非常大的问题。例...
    99+
    2023-06-15
  • linux中的free命令怎么用
    这篇文章给大家分享的是有关linux中的free命令怎么用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。Linux free 命令让我们看一下 free 命令的语法:free [options]free...
    99+
    2023-06-16
  • linux中free命令怎么使用
    本篇内容介绍了“linux中free命令怎么使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! ...
    99+
    2023-03-02
    linux free
  • props怎么在react中使用
    这篇文章给大家介绍props怎么在react中使用,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。组件的props( props是一个对象 )作用:接收传递给组件的数据特点:可以给组件传递任意类型的数据props是只读的...
    99+
    2023-06-14
  • Hook怎么在React中使用
    Hook怎么在React中使用?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。1、useState:让函数式组件拥有状态用法示例:// 计数器impor...
    99+
    2023-06-14
  • 怎么在React中使用Hooks
    这篇文章给大家介绍怎么在React中使用Hooks,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。一、State Hook1、基础用法function State(){  const&nbs...
    99+
    2023-06-14
  • hooks怎么在react中使用
    hooks怎么在react中使用?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。State Hooks案例:import { useState }&...
    99+
    2023-06-14
  • Context怎么在React中应用
    本篇文章给大家分享的是有关Context怎么在React中应用,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。Context定义和目的Context 提供了一种在组件之间共享数据...
    99+
    2023-06-15
  • MySQL中Innodb表Data free怎么计算
    这篇文章给大家分享的是有关MySQL中Innodb表Data free怎么计算的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。大概是空闲extent的大小。ST_FIELD_INF...
    99+
    2024-04-02
  • React 中 memo useMemo useCallback 到底该怎么用
    目录React.memo怎么用React.useMemo怎么用React.memo()和useMemo()的主要区别React.useCallback怎么用memo与useMemo及...
    99+
    2022-11-13
    React memo useMemo useCallback React useMemo useCallback
  • 怎么在React中完美运用
    这篇文章主要讲解了“怎么在React中完美运用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么在React中完美运用”吧!前言一直以来,ssh 身边都有很多小伙伴对 TS 如何在 Reac...
    99+
    2023-06-15
  • map在jquery中怎么使用
    这篇文章主要介绍“map在jquery中怎么使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“map在jquery中怎么使用”文章能帮助大家解决问题。 ...
    99+
    2024-04-02
  • 怎么在excel中做图表
    在Excel中制作图表非常简单。请按照以下步骤操作:1. 打开Excel并输入数据。将数据输入到工作表中的单元格中,确保每列和每行都...
    99+
    2023-09-29
    excel
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作