React v16.7 "Hooks" - What to Expect

简介: 什么是 Hooks? Hooks 是一个 React 函数组件内一类特殊的函数(通常以 “use” 开头,比如 “useState”),使开发者能够在 function component 里依旧使用 state 和 life-cycles,以及使用 custom hook 复用业务逻辑。

什么是 Hooks?

Hooks 是一个 React 函数组件内一类特殊的函数(通常以 “use” 开头,比如 “useState”),使开发者能够在 function component 里依旧使用 state 和 life-cycles,以及使用 custom hook 复用业务逻辑。

动机

在 React 里,function component 就是一个 pure render component,没有 state 和 component life-cycle。如果需要这两个中的任意一个,就需要变成 class component。在既有的 React API 下,这个模式有如下一些缺点:

组件间交流的耦合度很高,组件树臃肿

在既有的模式下,React 的组件间通信无非是两种,一种是单项数据流,另一种是通过 redux 之类的 global store 来实现全局状态和各组件间的解耦。当有些状态不适合放在 global store 的情况下,组件间逻辑的复用和沟通就变得十分困难(必须一层一层往下传)。这一点在 Higher order component (高阶组件) 和 render props 中尤其常见。我们为了复用一些逻辑,单独创造了很多 HOC(高阶组件) 来向下传递状态。这导致的问题就是当我们的应用规模变得越来越大的时候,一些无关 UI 的 wrapper 组件越来越多,React 组件树变得越来越臃肿(在 devtool 中可以甚至看到数十层 wrapper)。某些业务场景下,一个 Tooltip component 里面都嵌套了三四层额外的组件,使开发和调试的效率变得很低。

在新的 React hook 中,我们可以创建 custom hook,在其中复用一些逻辑,这些逻辑不再出现在组件树中,而是成为一个单独的,独立的逻辑单元,但是他们仍然响应 React 在渲染之间的变化。

JavaScript 的 class 产生的诸多疑惑

这一点是相对于 JavaScript 来说的。还记得刚入门 JavaScript 的时候,需要跨越的一个重要难关就是 ”this” 指向,以及原型链,继承这些问题。即使我们真正觉得明白了其中的原理,在日常的开发中也难免因为疏忽而踩坑,这一系列的问题导致新手相对比较难上手 React。举个简单的例子,React 组件内的 event listener 之前需要手动 bind this 的问题,这个问题就很难对一个 JavaScript 入门的新手解释明白。

而这一系列的问题,将在 Hook 中被极大地解决。如果没有 class,没有了 this,可能上述的种种问题都不再是问题了。

Write Hooks

说了这么多,Hooks API 是什么样呢?首先需要声明的是,Hooks 是向后兼容的,class component 不会被移除。作为开发者,可以慢慢迁移到这个新的 API。

Hooks 主要分为三种:

 ●  State hooks (在 function component 中使用 state)
 ●  Effect hooks (在 function component 中使用生命周期和 side effect)
 ●  Custom hooks (自定义 hooks 用来复用组件逻辑,解决了上述的第一个动机中阐述的问题,这一部分就不在此多费篇幅介绍了,请大家移步文档)。
State hooks
import { useState } from 'react';
function Example() {
 
// Declare a new state variable, which we'll call "count"
 
const [count, setCount] = useState(0);
 
return (
   
<div>
     
<p>You clicked {count} times</p>
     
<button onClick={() => setCount(count + 1)}>
       
Click me
     
</button>
   
</div>
 
);
}

之前讲过 hook 本质是一个特殊的函数(通常以 “use” 开头)。在这里,”useState” 就是一个 hook,通过它我们能够嵌入组件内部的 state。这个函数返回一个 pair,第一个值是当前对应这个 hook 的 state 值,第二个是怎样更新这个值。

我们可以从中感觉到,这两个返回值分别对应的以前的用法是:

 ●  this.state
 ●  this.setState

除此之外,我们还可以在一个函数组件中使用多个 useState:


function ExampleWithManyStates() {
 
// Declare multiple state variables!
 
const [age, setAge] = useState(42);
 
const [fruit, setFruit] = useState('banana');
 
const [todos, setTodos] = useState([{ text: 'Learn Hooks' }]);
 
// ...
}

这给我们的一个非常大的好处就是我们能够避免组件的 state 结构过于臃肿(因为之前每个 component class 只能有一个 state),能够独立处理每个 state。另一个好处就是这种写法非常直观,一眼就可以看出和这个 state 相关的两个变量,比如 [age, setAge]。

Effect hooks
import { useState, useEffect } from 'react';
function Example() {
 
const [count, setCount] = useState(0);
 
// Similar to componentDidMount and componentDidUpdate:
 useEffect
(() => {
   
// Update the document title using the browser API
   document
.title = `You clicked ${count} times`;
 
});
 
return (
   
<div>
     
<p>You clicked {count} times</p>
     
<button onClick={() => setCount(count + 1)}>
       
Click me
     
</button>
   
</div>
 
);
}

我们还需要解决一个问题,那就是怎样在 function component 里使用 life-cycles,生命周期函数。在这里,所有的 life-cycles,比如 componentDidMount, componentDidUpdate, shouldUpdate, 等等都集合成一个 Hook,叫做 useEffect。这个函数类似 redux 中的 subscribe,每当 React 因为 state 或是 props 而重新 render 的之后,就会触发 useEffect 里的这个 callback listener(在第一次 render 和每次 update 后触发)。

为什么叫 useEffect 呢?因为我们通常在生命周期内做的操作很多都会产生一些 side-effect(副作用)的操作,比如更新 DOM,fetch 数据,等等。

Other Built-in Hooks

除了 useState, useEffect 还有另外一些 React 自带的 hooks。比如:

 ●  useContext

替代了 <Context.Consumer> 使用 render props 的写法,使组件树更加简洁。

 ●  useReducer

相当于组件自带的 redux reducer,负责接收 dispatch 分发的 action 并更新 state。

详细用法请看文档。

总结

读到这里,你可能理解了为什么这个新的 API 被叫做 “Hooks” 了。”Hooks” 本意是”钩子“的意思。在 React 里,hooks 就是一系列特殊的函数,使函数组件 (functional component) 内部能够”钩住“ React 内部的 state 和 life-cycles。

这个向后兼容的 API 在解决了一些既有问题的情况下,不仅使我们能够更好地使用 state 和 life-cycles,真正功能强大的地方是使我们能够更轻松地复用组件逻辑(custom hooks)。但是限于篇幅,很多功能强大的部分和一些注意事项在这篇文章里并没有过多讲解,请大家移步官方文档学习更详细的姿势(墙裂推荐)。


原文发布时间为:2018-11-02

本文作者:cyan

本文来自云栖社区合作伙伴“前端大学”,了解相关信息可以关注“前端大学”。


相关文章
|
2月前
|
前端开发 JavaScript 开发者
深入理解React Hooks:提升前端开发效率的关键
【10月更文挑战第5天】深入理解React Hooks:提升前端开发效率的关键
|
2月前
|
前端开发 JavaScript
React Hooks 全面解析
【10月更文挑战第11天】React Hooks 是 React 16.8 引入的新特性,允许在函数组件中使用状态和其他 React 特性,简化了状态管理和生命周期管理。本文从基础概念入手,详细介绍了 `useState` 和 `useEffect` 的用法,探讨了常见问题和易错点,并提供了代码示例。通过学习本文,你将更好地理解和使用 Hooks,提升开发效率。
70 4
|
2月前
|
前端开发
深入解析React Hooks:构建高效且可维护的前端应用
本文将带你走进React Hooks的世界,探索这一革新特性如何改变我们构建React组件的方式。通过分析Hooks的核心概念、使用方法和最佳实践,文章旨在帮助你充分利用Hooks来提高开发效率,编写更简洁、更可维护的前端代码。我们将通过实际代码示例,深入了解useState、useEffect等常用Hooks的内部工作原理,并探讨如何自定义Hooks以复用逻辑。
|
2月前
|
前端开发 JavaScript API
探索React Hooks:前端开发的革命性工具
【10月更文挑战第5天】探索React Hooks:前端开发的革命性工具
|
18天前
|
前端开发 JavaScript
深入探索React Hooks:从useState到useEffect
深入探索React Hooks:从useState到useEffect
|
28天前
|
前端开发 JavaScript 开发者
“揭秘React Hooks的神秘面纱:如何掌握这些改变游戏规则的超能力以打造无敌前端应用”
【10月更文挑战第25天】React Hooks 自 2018 年推出以来,已成为 React 功能组件的重要组成部分。本文全面解析了 React Hooks 的核心概念,包括 `useState` 和 `useEffect` 的使用方法,并提供了最佳实践,如避免过度使用 Hooks、保持 Hooks 调用顺序一致、使用 `useReducer` 管理复杂状态逻辑、自定义 Hooks 封装复用逻辑等,帮助开发者更高效地使用 Hooks,构建健壮且易于维护的 React 应用。
32 2
|
2月前
|
前端开发 开发者
React 提供的其他重要 Hooks
【10月更文挑战第20天】React 提供了一系列强大的 Hooks,除了 `useRef` 之外,还有许多其他重要的 Hooks,它们共同构成了函数式组件开发的基础。
35 6
|
10天前
|
缓存 前端开发 开发者
深入理解React Hooks,打造高效响应式UI
深入理解React Hooks,打造高效响应式UI
20 0
|
2月前
|
前端开发 JavaScript 开发者
React Hooks
10月更文挑战第13天
35 1
|
2月前
|
前端开发