惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Tenable Blog
Last Week in AI
Last Week in AI
P
Proofpoint News Feed
Engineering at Meta
Engineering at Meta
H
Help Net Security
F
Fortinet All Blogs
MyScale Blog
MyScale Blog
宝玉的分享
宝玉的分享
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园 - 司徒正美
量子位
N
Netflix TechBlog - Medium
Apple Machine Learning Research
Apple Machine Learning Research
小众软件
小众软件
Recorded Future
Recorded Future
博客园 - 三生石上(FineUI控件)
Vercel News
Vercel News
aimingoo的专栏
aimingoo的专栏
I
InfoQ
Microsoft Security Blog
Microsoft Security Blog
Scott Helme
Scott Helme
The Last Watchdog
The Last Watchdog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
IT之家
IT之家
AI
AI
WordPress大学
WordPress大学
Security Archives - TechRepublic
Security Archives - TechRepublic
Google Online Security Blog
Google Online Security Blog
U
Unit 42
V2EX - 技术
V2EX - 技术
MongoDB | Blog
MongoDB | Blog
Schneier on Security
Schneier on Security
博客园 - Franky
H
Heimdal Security Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Jina AI
Jina AI
W
WeLiveSecurity
P
Privacy & Cybersecurity Law Blog
Cloudbric
Cloudbric
B
Blog RSS Feed
N
News | PayPal Newsroom
S
Securelist
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
I
Intezer
Hacker News - Newest:
Hacker News - Newest: "LLM"
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
博客园_首页
罗磊的独立博客
H
Hackread – Cybersecurity News, Data Breaches, AI and More
雷峰网
雷峰网

逐梦个人博客

使用原生JS监听浏览器的前进后退事件-逐梦个人博客 微信小程序中使用微信头像的实现方式-逐梦个人博客 如何在WebWorker中使用psd.js-逐梦个人博客 如何根据权重裁剪FaceApi.js返回的人脸数据-逐梦个人博客 在WebWorker中使用FaceAPI.js的正确姿势-逐梦个人博客 React通用带上下文的组件ID实现方案-逐梦个人博客 关于照片Exif Orientation信息的处理-逐梦个人博客 防止其他网站通过iframe嵌套自己站点的两种方式-逐梦个人博客 警惕!wordpress站长必知的重大安全漏洞合集-逐梦个人博客
解锁React组件函数this绑定新方式-逐梦个人博客
Dean · 2023-10-07 · via 逐梦个人博客

在定义React类组件的时候,我们经常需要在constructor中对函数做this的绑定,例如:

// components/TestComponent/index.js
class TestComponent extends PureComponent {
    constructor(props) {
        super(props);

        this.handleClick = this.handleClick.bind(this);
        this.handleMouseOver = this.handleMouseOver.bind(this);
        this.otherFunc = this.otherFunc.bind(this);
    }

    handleClick() {
        console.log('点击了');
    }

    handleMouseOver() {
        console.log('鼠标移入了');
    }

    otherFunc() {
        console.log('其他功能');
    }

    render() {
        <div onClick={this.handleClick} onMouseOver={this.handleMouseOver}>Test</div>
    }
}

export default TestComponent;

相信很多开发者对这种使用方式都不陌生,也会经常使用,但这种方式真的好吗?试想一下以下问题:

1、每增加一个处理函数都需要在constructor中增加一个this绑定,这种方式不累吗?

2、当一个组件依赖的处理函数特别多时,全部放在constructor中绑定,代码不会显得很臃肿吗?

3、当不同类型的处理函数需要在constructor中做this绑定时(比如事件处理函数,辅助函数等等),代码组织上会不会有些混乱?

上面提出了3个问题(当然可能还有别的问题),我们该如何去解决这3个问题呢?这里我直接给出我的解决方案,然后我们再看怎么使用。

为了解决上面的问题,我定义了一个组件的辅助函数:

// utils/component.js
export function bindFuncs(ctx, funcs, nameSpace = '') {
  const context = nameSpace ? (ctx[nameSpace] = {}) : ctx;
  Object.keys(funcs).forEach(func => {
    context[func] = (...args) => funcs[func](ctx, ...args);
  });
}

该函数接受3个参数:

ctx: 需要绑定的环境,一般为this

funcs:需要绑定环境的函数列表

nameSpace:函数绑定的命名空间

然后我们重构一下上面的TestComponent组件,首先我们需要将不同类型的处理函数分别管理,如下:

// components/TestComponent/handle/events.js
export function handleClick() {
    console.log('点击了');
}

export function handleMouseOver() {
    console.log('鼠标移入了');
}
// components/TestComponent/handle/handlers.js
export function otherFunc() {
    console.log('其他功能');
}

我们将事件处理函数维护在event.js中,将一些其他的函数维护在handlers.js中,然后使用我们定义的bindFuncs函数来优化组件,如下:

// components/TestComponent/index.js:
import { bindFuncs } from '../utils/components';

import * as handlers from './handle/handlers';
import * as eventHandlers from './handle/events';

class TestComponent extends PureComponent {
    constructor(props) {
        super(props);

        bindFuncs(this, handlers);
        bindFuncs(this, eventHandlers, 'events');
    }

    render() {
        <div {...this.events}>Test</div>
    }
}

优化后的代码是不是瞬间感觉干净了很多,我们将事件处理函数挂载到了this.events下,使用时只需要解构this.events即可,而且如果我们后期需要新增事件处理函数,只需要在events.js中新增对应的函数并导出即可,而不需要再做一些其他的操作,而对于otherFunc, 由于我们将handlers挂载到了this下,所以可以直接通过this.otherFunc即可访问该函数,后期新增普通处理函数,仅仅需要再handlers新增函数并导出。

今天的内容到此就结束了,如果你有更好的方式,欢迎留言一起交流学习。