Hook初识及简单了解

一. 认识hook

1. 为什么需要hook

Hook 是 React 16.8 的新增特性,它可以让我们在不编写class的情况下使用state以及其他的React特性(比如生命周期)。

我们先来思考一下class组件相对于函数式组件有什么优势?比较常见的是下面的优势:

  • 1.class组件可以定义自己的state,用来保存组件自己内部的状态;
    1.函数式组件不可以,因为函数每次调用都会产生新的临时变量;
  • 2.class组件有自己的生命周期,我们可以在对应的生命周期中完成自己的逻辑;比如在componentDidMount中发送网络请求,并且该生命周期函数只会执行一次;
    2.函数式组件在学习hooks之前,如果在函数中发送网络请求,意味着每次重新渲染都会重新发送一次网络请求;
  • 3.class组件可以在状态改变时只会重新执行render函数以及我们希望重新调用的生命周期函数componentDidUpdate等;
    3.函数式组件在重新渲染时,整个函数都会被执行,似乎没有什么地方可以只让它们调用一次;

所以,在Hook出现之前,对于上面这些情况我们通常都会编写class组件。

1.1 class组件的问题:
1.1.1复杂组件变得难以理解:
  • 在最初编写一个class组件时,往往逻辑比较简单,并不会非常复杂。
  • 但是随着业务的增多,我们的class组件会变得越来越复杂;
  • 比如componentDidMount中,可能就会包含大量的逻辑代码:包括网络请求、一些事件的监听(还需要在componentWillUnmount中移除);
  • 而对于这样的class实际上非常难以拆分:因为它们的逻辑往往混在一起,强行拆分反而会造成过度设计,增加代码的复杂度;
1.1.2 难以理解的class:
  • 很多人发现学习ES6的class是学习React的一个障碍。
  • 比如在class中,我们必须搞清楚this的指向到底是谁,所以需要花很多的精力去学习this;
  • 虽然我认为前端开发人员必须掌握this,但是依然处理起来非常麻烦;
1.1.3 组件复用状态很难:
  • 在前面为了一些状态的复用我们需要通过高阶组件或render props;
  • 像我们之前学习的redux中connect或者react-router中的withRouter,这些高阶组件设计的目的就是为了状态的复用;
  • 或者类似于Provider、Consumer来共享一些状态,但是多次使用Consumer时,我们的代码就会存在很多嵌套;
  • 这些代码让我们不管是编写和设计上来说,都变得非常困难;

2.Hook了解

Hook的出现,可以解决上面提到的这些问题;

2.1 简单总结一下hooks:
  • 它可以让我们在不编写class的情况下使用state以及其他的React特性;
  • 但是我们可以由此延伸出非常多的用法,来让我们前面所提到的问题得到解决;
2.2 Hook的使用场景:
  • Hook的出现基本可以代替我们之前所有使用class组件的地方(除了一些非常不常用的场景);
  • 但是如果是一个旧的项目,你并不需要直接将所有的代码重构为Hooks,因为它完全向下兼容,你-- 可以渐进式的来使用它;
  • Hook只能在函数组件中使用,不能在类组件,或者函数组件之外的地方使用;

3.hooks的基本演练

我们通过一个计数器案例,来对比一下class组件和函数式组件结合hooks的对比:
class组件实现:

import React, {
    PureComponent } from 'react'

export default class Counter01 extends PureComponent {
   
  constructor(props) {
   
    super(props);

    this.state = {
   
      counter: 0
    }
  }

  render() {
   
    return (
      <div>
        <h2>当前计数: {
   this.state.counter}</h2>
        <button onClick={
   e => this.increment()}>+1</button>
        <button onClick={
   e =>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个简单的 inline hook 示例代码,可以用于 hook 指定的函数,在调用该函数时打印日志信息: ```c++ #include <stdio.h> #include <unistd.h> #include <stdint.h> #include <sys/mman.h> #define HOOK_SIZE 12 // 用于 hook 的函数 void my_function() { printf("my_function called\n"); } // 原始函数 void (*original_function)(); void original_function_impl() { // 执行原始函数实现 } // Hook 函数 void hook_function() { printf("hook_function called\n"); // 调用原始函数 original_function(); } // Hook 函数的字节码 unsigned char hook_code[HOOK_SIZE] = { 0x68, 0x00, 0x00, 0x00, 0x00, // push 0x00000000 0xe9, 0x00, 0x00, 0x00, 0x00, // jmp hook_function 0x90 // nop }; // inline hook 函数 void inline_hook(void *target, void *hook) { // 将目标函数的前 HOOK_SIZE 字节设置为可写 mprotect(target, HOOK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC); // 保存原始函数地址 original_function = (void (*)())target; // 将 Hook 函数地址写入 Hook 代码中 *(uint32_t *)(hook_code + 1) = (uint32_t)hook - (uint32_t)target - HOOK_SIZE; // 将 Hook 代码写入目标函数中 memcpy(target, hook_code, HOOK_SIZE); // 将目标函数的前 HOOK_SIZE 字节设置为只读可执行 mprotect(target, HOOK_SIZE, PROT_READ | PROT_EXEC); } int main() { // 执行原始函数 original_function_impl(); // inline hook 目标函数 inline_hook((void *)original_function_impl, (void *)hook_function); // 再次执行原始函数 original_function_impl(); return 0; } ``` 请注意,该示例代码仅用于演示 inline hook 的原理,实际使用中可能需要更加复杂的实现。此外,inline hook 可能会涉及到一些风险,需要谨慎使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值