理解React Hooks看这一篇就够了

news/2024/7/15 19:20:53 标签: react.js, javascript, 前端

一、理解什么是Hooks

在React中,Hooks其实就是一个函数,这个函数的命名以use开头、函数return一个结果;React Hooks其实就是封装了一些通用的、公共的方法,就是一些通用的工具。

二、官方Hooks

官方Hooks是指React官方推荐的一些Hooks,如:useState、useEffect、useContext、useRef、useMemo、useCallback、useReducer、......;

1.useState

让React函数组件也可以使用状态,使用方法:const [ age, setAge ] = useState(35).

2.useEffect

在React函数组件里,没有组件生命周期这一说法,所以可以使用useEffect来替代组件生命周期,使用方法如下:

javascript">useEffect( () => {
    window.addEventListener('message', handleMessage );

    return () => {
        window.removeEventListener('message', handleMessage );
    }
}, [] )

useEffect接收的一个回调函数相当于是componentDidMount和componentDidUpdate,回调函数return的这一个回调相当于是componentWillUnmount;useEffect接收的第二个数组是依赖项,如果只是模拟组件生命周期,可以传空数组,通常这个依赖项不要传入过多或过于复杂,因为当依赖项发生变化useEffect中的回调函数会重新执行。

3.useContext

用于父组件向子组件的跨级传参,使用比较简单,直接参考官方文档即可。

4.useRef

绑定元素ref,通常用于调用子组件身上的方法;this.formRef.current.doReq()...。

5.useMemo

用于缓存函数的计算结果,与Vue中的计算属性类似;使用方法如下:

javascript">const result = useMemo( () => {
    const res = a + b;
    return res;
}, [a,b] )

useMemo的第二个参数为依赖项数组,依赖项发生变化则重新计算结果。

6.useCallback

缓存函数(缓存函数地址),通常与React.memo()一起使用;React.memo()是通过校验props中的数据是否改变的来决定组件是否需要重新渲染的一种缓存技术,具体点说React.memo()其实是通过校验Props中的数据的内存地址是否改变来决定组件是否重新渲染组件的一种技术。useCallback通常用于缓存父组件向子组件传递的函数,当父组件发生变化时会重新渲染,此时若变化与子组件无关,子组件不应重复渲染;useCallBack并不能阻止函数重新创建,它只能通过依赖决定返回新的函数还是旧的函数,从而在依赖不变的情况下保证函数地址不变。其使用方法如下:

javascript">import {useCallBack,memo} from 'react';

const Parent = ( props ) => {
    const [parentData, setParentData] = useState(66);  
    
    const toChildFun = useCallBack( () => {
        console.log("需要传入子组件的函数");
        
    }, [])
    
    return (<div>
          <Button onClick={() => setParentState(val => val+1)}>
              点击改变父组件中与Child组件无关的state
          </Button>
          
          <Child fun={toChildFun}></Child>
    <div>)
}

const Child = memo(( props ) => {
    console.log('子组件渲染了');
    return <div>子组件<div>
} )

7.useReducer

相当于写redux,直接根据官方文档进行使用。

三、自定义Hooks

官方文档里还有一些其他的Hooks,其实使用起来都比较方便,直接看文档使用就行了,在这里就列举以上几种常用的官方Hooks。

自定义Hooks其实就是根据自己的开发需求,封装一些通用的、公共的工具函数,使用起来其实就和官方推荐的Hooks是一样的。

总结:

自定义 Hooks 允许共享有状态逻辑,而不是状态本身,例如:

javascript">import { useState } from 'react';
// 自定义Hooks 
function useCounter(initialValue) {
  const [count, setCount] = useState(initialValue);
  function increment() {
    setCount(count + 1);
  }
  return [count, increment];
}

// 在其他组件进行使用
import useCounter from './useCounter';
function Counter() {
	const [count1, increment1] = useCounter(0);
	const [count2, increment2] = useCounter(100);
  return (
    <div>
      <p>Count1: {count1}</p>
      <button onClick={increment1}>Increment1</button>
       <p>Count2: {count2}</p>
      <button onClick={increment2}>Increment2</button>
    </div>
  );
}

当我们点击 Increment2 时,并不会影响 count1 ,因为每一个 useCounter 的调用都是独立的,其内部状态也是独立的。

四、React Hooks的使用方法

1.只能在函数外层调用 Hook,不要在循环、条件判断或者子函数中调用。

2.只能在 React 的函数组件(顶部)和自定义 Hook 中调用 Hook。不要在其他 JavaScript 函数中调用。

3.在组件中 React 是通过判断 Hook 调用的顺序来判断某个 state 对应的 useState的,所以必须保证 Hook 的调用顺序在多次渲染之间保持一致,React 才能正确地将内部 state 和对应的 Hook 进行关联。

总结:

1.hooks的使用位置:在组件内的顶部使用。
2.hooks的使用原则:保证执行顺序不会改变。

五、用Hooks的优势是什么

所谓的hooks函数组件比类组件复用性更强是指:
1.当项目整体采用类组件时,如果要复用状态逻辑,只能使用高阶组件,因为一般也不会将类组件与hooks混合使用;
2.当项目整体采用函数组件时,如果要复用状态逻辑,直接使用自定义hooks即可;
所以才会有hooks函数组件比类组件复用性更强这一说法。

假如现在我们要让多个组件复用一个基于状态的逻辑公共方法:

1.使用高阶组件

javascript">import { Table } from 'antd'
import server from './server'

function useTable(server) {
  return function (WrappedComponent) {
    return class HighComponent extends React.Component {
      state = {
        tableProps: xxx, 
      };
      render() {
        const { tableProps } = this.state;
        return <WrappedComponent tableProps={tableProps} />;
      }
    };
  };
}

@useTable(server)
class App extends Component{
  render(){
    const { tableProps } = this.props;
    return (
      <Table 
        columns={[...]}
      
        {...tableProps}
      />
    )
  }
}

2.使用Hooks

javascript">import { Table } from 'antd'
import server from './api'

function useTable(server) {
  const [tableProps, setTableProps] = useState(xxx);
  return tableProps;
}

function App {
    const { tableProps } = useTable();
    return (
      <Table 
        columns={[...]}
      
        {...tableProps}
      />
    )
}

总结:

hooks对比的对象是高阶组件,二者的主要作用是:让多个组件可以复用基于状态的逻辑,也就是说组件复用的方法是基于状态的;

1.使用自定义hooks可以很方便的定义状态和逻辑,最后将状态和逻辑方法return出去,组件使用的时候直接引入,使用方法和使用官方hooks是一样的。

2.使用高阶组件实现状态逻辑复用是通过定义一个函数(这个函数就称为高阶组件),接收一个组件参数,return一个自定义的组件,在这个自定义的组件里面书写对应的状态和逻辑,最后render接收到的组件(参数)并将状态和逻辑以props的形式传递给这个的组件;组件在使用的时候就是使用这个函数(高阶组件)将要使用的组件包裹起来,在组件的props身上就可以拿到复用的状态和逻辑。

3.使用Hooks可以减少组件树的层级,防止组件深度嵌套,同时代码也更少更简洁。


http://www.niftyadmin.cn/n/5159489.html

相关文章

matlab 读写ENVI标准数据

本博客主要讲解如何读、生成ENVI标准格式的数据。主要分为四部分&#xff1a;读取ENVI头文件、读取ENVI数据、写入ENVI头文件、生成ENVI标准数据&#xff0c;最后附加讲解了本人写的生成hdr文本文件代码。此外&#xff0c;文中还具体介绍写代码的一些思路。 一、读取ENVI头文件…

6-会话、过滤器、监听器

6-会话、过滤器、监听器 文章目录 6-会话、过滤器、监听器会话会话概述为什么需要会话管理会话管理实现的手段 Cookie概述使用时效设置路径设置&#xff1a;特定请求才携带cookie SessionHttpSession的概述HttpSession的使用HttpSession的使用-getSession()方法原理HttpSession…

aosp定制android系统

目录 AOSP 准备工作(配置) 确定机型和版本 初始化 git安装 curl安装 同步源码 环境变量 创建aosp目录 指定同步版本 解下来安装编译需要的依赖 编译aosp源码 刷入系统 AOSP 全称 Android Open Source Project 是指Android开源项目&#xff0c;它是由Google主导的…

2023年十大地推拉新接单平台和网推接单平台,都是一手单

2023年做拉新推广的地推人员&#xff0c;一定不要错过这十个接单平台&#xff0c;助你轻松找到一手单&#xff0c;这10个平台分别是&#xff1a; 主推&#xff1a;“聚量推客” 一手官签接单平台 一手官方邀请码 000000 1. 聚量推客&#xff1a; “聚量推客”汇聚了众多市场…

技术分享 | app自动化测试(Android)-- 属性获取与断言

断言是 UI 自动化测试的三要素之一&#xff0c;是 UI 自动化不可或缺的部分。在使用定位器定位到元素后&#xff0c;通过脚本进行业务操作的交互&#xff0c;想要验证交互过程中的正确性就需要用到断言。 常规的UI自动化断言 分析正确的输出结果&#xff0c;常规的断言一般包…

洛谷P2196 [NOIP1996 提高组] 挖地雷【动态规划思路分析】看完直接举一反三!

P2196 [NOIP1996 提高组] 挖地雷 前言题目题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 题目分析注意事项 代码后话额外测试用例样例输入 #2样例输出 #2 王婆卖瓜 题目来源 前言 我发现我是天才&#xff0c;只做了三道动态规划的类型题就感觉我已经炉火纯青了。大…

第11章 Java集合(二)

目录 内容说明 章节内容 一、Set接口 二、HashSet集合 三、LinkedHashSet集合 四、TreeSet集合

RPA的前景怎么样?

近年来&#xff0c;随着人工智能相关政策的顶层设计逐渐完善&#xff0c;加上产业需求爆发与技术演进交叠之下&#xff0c;人工智能成为数字经济高质量发展的新引擎、新动力&#xff0c;并催生出RPA、AIGC等新板块&#xff0c;支撑着人工智能市场规模高速增长。而在国家大力发展…