千家信息网

怎么在React中做到jQuery-free

发表于:2025-01-16 作者:千家信息网编辑
千家信息网最后更新 2025年01月16日,这篇文章主要介绍怎么在React中做到jQuery-free,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!前言首先我们仍要说的是,jQuery 是现在***的 JavaScri
千家信息网最后更新 2025年01月16日怎么在React中做到jQuery-free

这篇文章主要介绍怎么在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 (             
just a demo
); } }

这是最简单的获取 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 (             
just a demo
); } }

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

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

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

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

有人可能会问,那子组件怎么拿父组件的 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 (             
{this.state.list.map((item) =>
{item}
)}
); } }

三、事件的监听

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 (             
点击我弹出弹框
); } }

这里有一个小细节就是 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 (             
just a demo
); } }

六、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 (             
this.rootNode = c} style={{ width: '100px', overflow: 'auto' }} >
just a demo
); } }

但是,在大部分的情况下,我们完全不需要做,因为 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 (             
跳转链接
); } }

七、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 (             
跳转链接
); } }

八、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 (             
just a demo
); } }

九、数据存储

比起 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 动画。

   {interpolatingStyle => 
}

以上是"怎么在React中做到jQuery-free"这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注行业资讯频道!

组件 元素 动画 事件 数据 属性 推荐 情况 节点 监听 方法 第三方 链接 插件 时候 版本 类名 处理 设计 驱动 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 开发费用网络安全费用比例 传奇数据库怎么设置备份 安卓软件开发设计说明书 mysql数据库整数字段 网络安全检测装置横向隔离 汽车网络安全测试系统 政府网络安全工程采购要求 科技互联网公司世界前300 永州软件开发培训好不好 电子商务数字媒体服务器 伊春跑腿app软件开发 北京乐游软件开发有限公司 我的世界日月宝可梦服务器金币 远程重启服务器 命令 肇庆服务器铝合金外壳 寅子帝国神话服务器 网络安全不涉及的范围是防黑客 福建省网络安全可信峰会 学校国家网络安全宣传周活动 系统集成和网络安全 服务器开关电源接口 网络安全需要国际合作 宝马中国软件开发 数据与计算机网络技术 无线网络安全的理解 黄山服务好的服务器机箱机柜 网络安全不涉及的范围是防黑客 灯具设计软件开发 利用数据库来了解人们的喜好 网络技术应用试题粤教版
0