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

推荐订阅源

美团技术团队
D
DataBreaches.Net
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
D
Docker
N
Netflix TechBlog - Medium
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
C
Check Point Blog
腾讯CDC
Stack Overflow Blog
Stack Overflow Blog
V
Visual Studio Blog
IT之家
IT之家
月光博客
月光博客
U
Unit 42
K
Kaspersky official blog
T
Threatpost
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
GbyAI
GbyAI
P
Proofpoint News Feed
Last Week in AI
Last Week in AI
云风的 BLOG
云风的 BLOG
酷 壳 – CoolShell
酷 壳 – CoolShell
I
InfoQ
Engineering at Meta
Engineering at Meta
Recorded Future
Recorded Future
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
S
Security @ Cisco Blogs
MyScale Blog
MyScale Blog
大猫的无限游戏
大猫的无限游戏
Security Archives - TechRepublic
Security Archives - TechRepublic
Webroot Blog
Webroot Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Hacker News - Newest:
Hacker News - Newest: "LLM"
S
Schneier on Security
S
Secure Thoughts
The Register - Security
The Register - Security
B
Blog RSS Feed
The Last Watchdog
The Last Watchdog
P
Palo Alto Networks Blog
爱范儿
爱范儿
B
Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
N
News and Events Feed by Topic
阮一峰的网络日志
阮一峰的网络日志
L
LINUX DO - 热门话题
C
Cisco Blogs
Spread Privacy
Spread Privacy
F
Full Disclosure
博客园 - 聂微东
T
The Blog of Author Tim Ferriss

逐梦个人博客

使用原生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新增函数并导出。

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