最终的React Hooks速查表

发布于:2021-02-02 10:25:20

0

88

0

webdev react javascript

React Hooks是React世界的新热点。我正在稳步地写越来越多的书,我想有一个参考的备忘单会很有用,它包含了基本的钩子和复杂的useEffect。查看官方的Hooks API参考以获取更深入的信息。

useEffect(用于生命周期方法)

useEffect等,允许您编写自己的副作用,并在需要时触发重新渲染。

但为了更简单,useffect还替代了生命周期方法。让我们谈谈他们。

替换componentDidUpdate+componentDidMount

什么时候开始?每次渲染

有什么问题吗?它不仅仅是一个componentDidUpdate替代品,它还可以在挂载上运行。所以不是1比1。

重要功能?useffect可以接受第二个参数,您必须跳过该参数。您也可以返回一个函数,我们将在下一节中介绍。

语法:

import { useEffect } from 'react'; useEffect(() => {   // whatever runs here will run on each re-render });

替换为componentDidMount+componentWillUnmount

什么时候开始?安装和卸载组件时

有什么问题吗?语法与前面的用例非常接近。好几次我都被它甩了,但只要你看了文件就明白了。如果效果运行多次,请确保传入了第二个参数

重要功能?这是一个只运行一次的效果。mount逻辑放在effect函数的主体中,unmount/cleanup逻辑放在从effect返回的函数中。

语法:

import { useEffect } from 'react'; useEffect(() => {   // run mount logic here such as fetching some data   return () => {     // unmount logic goes here   }; }, []); // note the empty array

您可以将mountunmount逻辑保留为空,以便只处理其中一个生命周期替代项。意思是:

  1. 保持mount逻辑为空,以便只有unmount逻辑运行(仅替换componentWillUnmount

  2. 不返回任何内容,以便只有mount逻辑运行(仅替换componentDidMount

useEffect的副作用

useEffect的主要目标是包含您可能想要使用的任何副作用。副作用本质上是你在你的组件中所做的影响整个世界的事情。无论是网络请求、设置文档标题,还是其他什么。

必要时运行

什么时候开始?当组件重新呈现时,useEffect将检查依赖项。如果依赖项值更改,useffect将运行该效果

有什么问题吗?React做了一个浅显的比较。如果您使用一个对象或一个数组,您的反应会认为没有改变。

重要特性useEffect在情况不变时跳过运行效果。实际上,您不必在效果中使用依赖项值。可以作为依赖项传入prop值。

语法:

import { useEffect } from 'react'; function SomeComponent(props) {      useEffect(() => {       // logic runs only when dependency variables changed     }, [arrOfDependency, values, props.id]); // array of values to check if they've changed }

潜在用例

由于钩子更难解释,我想提供一个用例列表

  1. 当道具更改以获取新数据时运行副作用(如获取)

  2. 仅当计算值更改时运行资源密集型计算

  3. 当值更新时更新页面(如文档标题)

useState

状态可能是人们从无状态(功能)组件切换到类组件的原因。useState允许我们拥有无类的有状态组件。

它返回什么?当前状态和用于设置状态的函数

有什么问题吗?状态设置函数将用新状态替换以前的状态,而不是像类状态那样合并它们。在设置状态之前,您需要自己合并对象。

重要功能您可以在组件中使用任意多个useState挂钩。将任何值传递给useState将创建初始状态。这也是一种惯例,不调用变量statesetState,而是使用上下文名称(例如usersetUser)。接受状态的任何值,它不必是对象。

语法:

import { useState } from 'react'; // setup const defaultValue = { name: "Antonin" }; const [state, setState] = useState(defaultValue); // scenario 1 usage // resulting state only contains key `user` with value 'antjanus' setState({ user: 'antjanus' });  // scenario 2 usage // resulting state contains key `name` with value 'A. Januska' setState({ name: 'A. Januska' });  // scenario 3 usage // resulting state is a merger between `{ name: 'A. Januska' }` and `{ user: 'antjanus'}` setState({ ...state, user: 'antjanus'});

useReducer

useReduceruseState的另一种选择,如果您以前使用过Redux,这看起来会很熟悉。

有什么争论?它返回什么?useReducer采用reducer函数和initialState。它返回当前的state和adispatcher(听起来很熟悉?)

它是如何运行的?在状态更改时,dispatch具有类型和数据有效负载的对象(有关更多信息,请参阅flux标准操作)。传递给useReducer的reducer将接收当前状态和已调度对象。它返回新状态。

有什么问题吗?这是一个更复杂的工作流,但它的工作原理与您使用Redux时所期望的一样。

重要功能减速机每次调度都会运行。它可以访问以前的状态。useReducer还包括可用于创建初始状态的第三个参数。

语法

import { useReducer } from 'react'; function reducer(currentState, action) {   switch(action.type) {      // handle each action type and how it affects the current state here   } } function SomeComponent() {   const [state, dispatch] = useReducer(reducer, initialState);   dispatch({ type: 'ADD', payload: data }); // { type: 'ADD', payload: data } gets passed into the `reducer` as the `action` argument while `state` gets passed in as the `currentState` argument }

建立自己的钩子

关于构建自己的钩子的简短说明。这就像使用现有的钩子并将它们组合在一个以use开头的函数中一样简单。下面是一个useUser钩子的快速示例。

有什么要求?函数以关键字use开始。例如useUseruseSomethingElse

重要特性:您可以调用自定义钩子中的任何钩子,并按预期工作。

语法:

import { useEffect } from 'react'; function useUser(userId) {   let [user, setUser] = useState(null);   useEffect(() => {     fetch(`/api/user/${userId}`)         .then(data => data.toJSON())         .then(data => setUser(data));   }, [userId]);   return user; } function SomeComponent(props) {   const user = useUser(props.id); }

剩下的呢?

您还可以使用其他挂钩,如useMemouseCallback等等。我想说那些是更高级的钩子,如果你了解基本的钩子,那就去看看官方文档吧。

我也知道其中有很多高级用法示例(比如将useReducer的dispatch传递到几个级别)。

如果您发现一些不正确的或一些额外的有用的信息是不包括在内,让我知道!我会把它包括在内!