iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >一起来了解React的Hook
  • 296
分享到

一起来了解React的Hook

2024-04-02 19:04:59 296人浏览 八月长安
摘要

目录StateHook声明多个state变量那么,什么是Hook?EffectHookHook使用规则自定义Hook其他Hook总结State Hook 这个例子用来显示一个计数器。

State Hook

这个例子用来显示一个计数器。当你点击按钮,计数器的值就会增加:

import React, { useState } from 'react';
function Example() {
  // 声明一个叫 “count” 的 state 变量。
  const [count, setCount] = useState(0);
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

在这里,useState 就是一个 Hook (等下我们会讲到这是什么意思)。通过在函数组件里调用它来给组件添加一些内部 state。React 会在重复渲染时保留这个 stateuseState 会返回一对值:当前状态一个让你更新它的函数,你可以在事件处理函数中或其他一些地方调用这个函数。它类似 class 组件的 this.setState,但是它不会把新的 state 和旧的 state 进行合并。(我们会在使用 State Hook 里展示一个对比 useState 和 this.state 的例子)。

useState 唯一的参数就是初始 state。在上面的例子中,我们的计数器是从零开始的,所以初始 state 就是 0。值得注意的是,不同于 this.state,这里的 state 不一定要是一个对象 —— 如果你有需要,它也可以是。这个初始 state 参数只有在第一次渲染时会被用到。

声明多个 state 变量

你可以在一个组件中多次使用 State Hook:

function ExampleWithManyStates() {
  // 声明多个 state 变量!
  const [age, setAge] = useState(42);
  const [fruit, setFruit] = useState('banana');
  const [todos, setTodos] = useState([{ text: 'Learn Hooks' }]);
  // ...
}

数组解构的语法让我们在调用 useState 时可以给 state 变量取不同的名字。当然,这些名字并不是 useState api 的一部分。React 假设当你多次调用 useState 的时候,你能保证每次渲染时它们的调用顺序是不变的。后面我们会再次解释它是如何工作的以及在什么场景下使用。

那么,什么是 Hook?

Hook 是一些可以让你在函数组件里 " 钩入" React state 及生命周期等特性的函数。Hook 不能在 class 组件中使用 —— 这使得你不使用 class 也能使用 React。(我们不推荐把你已有的组件全部重写,但是你可以在新组件里开始使用 Hook。)

React 内置了一些像 useState 这样的 Hook。你也可以创建你自己的 Hook 来复用不同组件之间的状态逻辑。我们会先介绍这些内置的 Hook。

Effect Hook

你之前可能已经在 React 组件中执行过数据获取、订阅或者手动修改过 DOM。我们统一把这些操作称为“副作用”,或者简称为“作用”。

useEffect 就是一个 Effect Hook,给函数组件增加了操作副作用的能力。它跟 class 组件中的 componentDidMountcomponentDidUpdate 和 componentWillUnmount 具有相同的用途,只不过被合并成了一个 API。

例如,下面这个组件在 React 更新 DOM 后会设置一个页面标题:

import React, { useState, useEffect } from 'react';
function Example() {
  const [count, setCount] = useState(0);
  // 相当于 componentDidMount 和 componentDidUpdate:
  useEffect(() => {
    // 使用浏览器的 API 更新页面标题
    document.title = `You clicked ${count} times`;
  });
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

当你调用 useEffect 时,就是在告诉 React 在完成对 DOM 的更改后运行你的“副作用”函数。由于副作用函数是在组件内声明的,所以它们可以访问到组件的 props 和 state。默认情况下,React 会在每次渲染后调用副作用函数 —— 包括第一次渲染的时候。

副作用函数还可以通过返回一个函数来指定如何“清除”副作用。例如,在下面的组件中使用副作用函数来订阅好友的在线状态,并通过取消订阅来进行清除操作:

import React, { useState, useEffect } from 'react';
function FriendStatus(props) {
  const [isOnline, setIsOnline] = useState(null);
  function handleStatusChange(status) {
    setIsOnline(status.isOnline);
  }
  useEffect(() => {
    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
  });
  if (isOnline === null) {
    return 'Loading...';
  }
  return isOnline ? 'Online' : 'Offline';
}

在这个示例中,React 会在组件销毁时取消对 ChatAPI 的订阅,然后在后续渲染时重新执行副作用函数。(如果传给 ChatAPI 的 props.friend.id 没有变化,你也可以告诉 React 跳过重新订阅。)

跟 useState 一样,你可以在组件中多次使用 useEffect :

function FriendStatusWithCounter(props) {
  const [count, setCount] = useState(0);
  useEffect(() => {
    document.title = `You clicked ${count} times`;
  });
  const [isOnline, setIsOnline] = useState(null);
  useEffect(() => {
    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
  });
  function handleStatusChange(status) {
    setIsOnline(status.isOnline);
  }
  // ...

通过使用 Hook,你可以把组件内相关的副作用组织在一起(例如创建订阅及取消订阅),而不要把它们拆分到不同的生命周期函数里。

Hook 使用规则

Hook 就是 javascript 函数,但是使用它们会有两个额外的规则:

  • 只能在函数最外层调用 Hook。不要在循环、条件判断或者子函数中调用。
  • 只能在 React 的函数组件中调用 Hook。不要在其他 JavaScript 函数中调用。(还有一个地方可以调用 Hook —— 就是自定义的 Hook 中,我们稍后会学习到。)

自定义 Hook

有时候我们会想要在组件之间重用一些状态逻辑。目前为止,有两种主流方案来解决这个问题:高阶组件和 render props。自定义 Hook 可以让你在不增加组件的情况下达到同样的目的。

前面,我们介绍了一个叫 FriendStatus 的组件,它通过调用 useState 和 useEffect 的 Hook 来订阅一个好友的在线状态。假设我们想在另一个组件里重用这个订阅逻辑。

首先,我们把这个逻辑抽取到一个叫做 useFriendStatus 的自定义 Hook 里:

import React, { useState, useEffect } from 'react';
function useFriendStatus(friendID) {
  const [isOnline, setIsOnline] = useState(null);
  function handleStatusChange(status) {
    setIsOnline(status.isOnline);
  }
  useEffect(() => {
    ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange);
    };
  });
  return isOnline;
}

它将 friendID 作为参数,并返回该好友是否在线:

现在我们可以在两个组件中使用它:

function FriendStatus(props) {
  const isOnline = useFriendStatus(props.friend.id);
  if (isOnline === null) {
    return 'Loading...';
  }
  return isOnline ? 'Online' : 'Offline';
}
function FriendListItem(props) {
  const isOnline = useFriendStatus(props.friend.id);
  return (
    <li style={{ color: isOnline ? 'green' : 'black' }}>
      {props.friend.name}
    </li>
  );
}

每个组件间的 state 是完全独立的。Hook 是一种复用状态逻辑的方式,它不复用 state 本身。事实上 Hook 的每次调用都有一个完全独立的 state —— 因此你可以在单个组件中多次调用同一个自定义 Hook。

自定义 Hook 更像是一种约定而不是功能。如果函数的名字以 use 开头并调用其他 Hook,我们就说这是一个自定义 Hook。 useSomething 的命名约定可以让我们的 linter 插件在使用 Hook 的代码中找到 bug。

你可以创建涵盖各种场景的自定义 Hook,如表单处理、动画、订阅声明、计时器,甚至可能还有更多我们没想到的场景。我们很期待看到 React 社区会出现什么样的自定义 Hook。

其他 Hook

除此之外,还有一些使用频率较低的但是很有用的 Hook。比如,useContext 让你不使用组件嵌套就可以订阅 React 的 Context。

function Example() {
  const locale = useContext(LocaleContext);
  const theme = useContext(ThemeContext);
  // ...
}

另外 useReducer 可以让你通过 reducer 来管理组件本地的复杂 state

function Todos() {
  const [todos, dispatch] = useReducer(todosReducer);
  // ...

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注编程网的更多内容!   

--结束END--

本文标题: 一起来了解React的Hook

本文链接: https://www.lsjlt.com/news/142695.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 一起来了解React的Hook
    目录StateHook声明多个state变量那么,什么是HookEffectHookHook使用规则自定义Hook其他Hook总结State Hook 这个例子用来显示一个计数器。当...
    99+
    2024-04-02
  • 一起来了解python的运算符
    目录1、算数运算符2、比较运算符3、赋值运算符4、成员运算符实例5、身份运算符实例6、逻辑运算符实例逻辑短路逻辑优先级7、位运算符按位与按位或按位非按位异或右移左移8.运算符的优先级...
    99+
    2024-04-02
  • 一起来了解一下C++中的指针
    目录1指针的基本概念2指针变量的定义和使用3指针所占内存空间4空指针和野指针5const修饰指针6指针和数组7指针和函数8指针、数组、函数总结1 指针的基本概念 作用:可以通过指针间...
    99+
    2024-04-02
  • 一起来了解mysql数据库
    目录一、数据库是什么?二、数据库的分类?三、数据库和数据结构的区别四、MySQL数据库的介绍4.1 MySQL数据库的组成4.2 MySQL服务器的介绍4.3 MySQL数据库的数据...
    99+
    2024-04-02
  • 一起来了解javascript数组的方法
    目录1、push2、pop3、unshift()4、shift()5、concat()6、reverse()7、sort()8、join()9、slice()10...
    99+
    2024-04-02
  • 一起来了解一下C++的结构体 struct
    目录struct 结构体占用空间与类的区别访问控制权限主要用途c结构体实现虚函数的功能总结struct 结构体 占用空间 在C++ 中空结构体占1个字节 struct Temp{};...
    99+
    2024-04-02
  • 一起来了解JavaScript面向对象
    目录JavaScript原型链Object的原型顶层原型创建Object对象的内存图Object是所有类的父类原型链实现继承借用构造函数实现继承总结JavaScript原型链 每一个...
    99+
    2024-04-02
  • 一起来了解Java的File类和IO流
    目录1.IO流介绍IO流体系结构2.Java中流的分2.1按流向分:2.2按数据传输单位分:2.3按功能分:3.File类介绍3.1file类的作用3.2file类构造函数3.3绝对...
    99+
    2024-04-02
  • 一起来了解c语言的str函数
    目录strlen:strcmp:strcpy:strcat:strstr:atoi:总结strlen: 用于求字符串长度,从首字符开始,到'\0'结束,'\0...
    99+
    2024-04-02
  • 一起来了解python的if流程控制
    目录1、流程控制和分支结构流程控制分支结构2、if的单分支结构3、if的双分支结构4、if的多分支结构5、巢状分支总结1、流程控制和分支结构 流程控制 概念: 流程:代码执行的过程...
    99+
    2024-04-02
  • 一起来了解JavaScript的变量作用域
    目录1.变量作用域的分析2.var关键字3.let和const关键字4.var、let和const的对比总结1.变量作用域的分析 首先,我们先研究一下JavaScript的变量作用域...
    99+
    2024-04-02
  • JavaScript的防抖和节流一起来了解下
    目录1. 前言2. 函数防抖(debounce)延迟防抖前缘防抖防抖函数实现总结3. 函数节流(throttling)延迟节流前缘节流节流函数实现总结4. 两者区别5. 应用场景总结...
    99+
    2024-04-02
  • Python进程间的通信一起来了解下
    目录通信方式Queue介绍:生产者和消费者模型为什么要使用生产者和消费者模式什么是生产者消费者模式实现方式一:Queue实现方式二:利用JoinableQueue总结通信方式 进程彼...
    99+
    2024-04-02
  • 一起来了解python的基本输入和输出
    目录Python基本输入和输出1.input输入函数2.print输出函数2.1print输出颜色控制(终端有效)总结Python基本输入和输出 1.input输入函数 input函...
    99+
    2024-04-02
  • 一起来学习React元素的创建和渲染
    目录React和ReactDOMReact初体验创建React元素JSXJSX初体验总结React 是一个用于构建用户界面的 JavaScript 库 它包括两个库:react.js...
    99+
    2024-04-02
  • 一起来了解下Swiper插件的使用和介绍
    目录Swiper介绍swiper的使用代码实现总结Swiper介绍 swiper是一款开源的解决前端开发中触摸滑动案例的插件 swiper官网: swiper的使用 使用swipe...
    99+
    2024-04-02
  • 你了解PHP中的数据类型吗?一起来学习!
    PHP是一种广泛应用于Web开发的编程语言,它支持多种数据类型。在使用PHP进行开发时,了解和正确使用不同的数据类型是非常重要的。本文将详细介绍PHP中的数据类型,并提供一些演示代码。 布尔型(Boolean) 布尔型表示两个状态:tr...
    99+
    2023-07-09
    数据类型 学习笔记 http
  • 深入理解React的自定义Hook
    自定义 Hooks 的核心是共享组件之间的逻辑。使用自定义 Hooks 能够减少重复的逻辑,更重要的是,自定义 Hooks 内部的代码描述了它们想做什么,而不是如何做。当你将逻辑提取到自定义Hooks 中时,你可以隐藏如何处理某些"...
    99+
    2023-05-14
    前端 代码规范 React.js
  • React Hook中的useState函数的详细解析
    useState => 让函数组件具有维持状态的能力useState 这个 Hook 是用来管理 state 的,它可以让函数组件具有维持状态的能力。即在一个函数组件的多次渲染...
    99+
    2022-11-13
    React Hook  useState函数 React Hook
  • 一起了解了解MySQL存储引擎
    目录前言一、MySQL主要存储引擎:二、实例介绍它们(不同的存储引擎在存储表的时候的异同点)前言 在日常生活中文件格式有很多种,并且针对不同的文件格式会有对应不同存储方式和处理机制(...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作