如何 正确看待react Hooks

104 阅读4分钟

大家好,我是muddyrain,一个前端小🔥,热爱前端以及热爱开发.

Hooks? 这是个什么东西 -- google-translate 一下 哦,中文的意思是个钩子的意思啊.

React16.8版本以前我们写项目都是使用 ReactClass 类声明来进行组件页面的实现的,但是有很多痛点,我们需要去继承 React.component 以及需要 初始化构建还需要定义各种声明很长名字声明周期来写。

但是,从16.8react给我们出了一个新的特性一个全新的概念,但也支持原有的class方式组件而且还可以共用互用,不得不说react为我们开发迭代想的很周全.

官方简介是这样说的:

Hooks are a new addition in React 16.8. They let you use state and other React features without writing a class.

翻译过来的意思就是:

hooks 是 react16.8新推出的特性, 他可以让你不用使用class就可以写出 state状态以及其他react特性

2022-08-04 10-43-59.2022-08-04 10_44_13.gif

哈哈,英文不是很好目前正在学习,并且正在努力尝试不用翻译来阅读官方英文文档.

没有破坏性改动 - 官方标注

下面我们谈下一共推出了几种新 hooksAPi

  • useState - 状态
  • useEffect - 副作用
  • useContext - 上下文 格外其他的hooks
  • useReducer - 状态管理
  • useCallback - 回调函数 - 用来解决一些必要的渲染
  • useMemo - 渲染回调 - 会在每次渲染的时候去执行回调
  • useRef - ref对象
  • useImperativeHandle - 暴露实例值给父组件
  • useLayoutEffect - 在所有dom加载完后进行副作用
  • useTransition - 过渡任务
  • useId - 服务器与客户端建立链接需要接受稳定Id

useState 状态

官网案例是这样子的:

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>
  );
}

在 class 中,我们通过在构造函数中设置 this.state 为 { count: 0 } 来初始化 count state 为 0:

class Example extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }

在函数组件中,我们没有 this,所以我们不能分配或读取 this.state。我们直接在组件中调用 useState Hook:

import React, { useState } from 'react';

function Example() {
  // 声明一个叫 “count” 的 state 变量
  const [count, setCount] = useState(0);
}

经过俩次对比我们大致了解出了, useState就是创建了个状态 返回的是个拥有俩个值数组,可以用数组结构的方式直接展示出来.(更好的可以自定义变量)

第一个变量 count 是当前状态值, 第二个 setCount是一个函数,直接执行的话可以设置改变当前的值,也可以接收一个回调来进行异步后操作.

读取 State:

当我们想在 class 中显示当前的 count,我们读取 this.state.count

  <p>You clicked {this.state.count} times</p>

在函数中,我们可以直接用 count:

  <p>You clicked {count} times</p>

更新 State:

class 中,我们需要调用 this.setState() 来更新 count 值:

  <button onClick={() => this.setState({ count: this.state.count + 1 })}>
    Click me
  </button>

在函数中,我们已经有了 setCountcount 变量,所以我们不需要 this:

  <button onClick={() => setCount(count + 1)}>
    Click me
  </button>

useContext 副作用

Effect Hook 可以让你在函数组件中执行副作用操作

官方案例:

import React, { 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>
  );
}

如果你熟悉Reactclass的生命周期函数,你可以把 useEffect Hook 当做 componentDidMount componentDidUpdate componentWillUnmount 这三个函数的组合。

Effect Hook 副作用钩子做了什么?

有俩个参数, 第一个为 回调函数, 第二个为 需要进行监听的值(可以为空,意思作为监听全部的状态值)

通过上方的案例不难看出来 第二个参数没有传递, 那就是监听了整体组件里的状态,但目前组件里只有一个 count 状态, count初始化的时候是个 0 ,那么这个副作用函数也会去执行一次.

下方的 jsx 有一个点击事件用来设置 count状态值,那么这个意思就是 如果这个 count值变化了,那么 useEffect就会再次被执行 执行力有一个动态依赖 ${count} 那么就回去获取 这个值会随着响应变化来进行更改.所以为就形成了副作用.

如果我们把 effect改为这样的:

useEffect(() => {
  document.title = `You clicked ${count} times`;
}, [count]); // 仅在 count 更改时更新

那么就会被监听 只有在 count变化后才可以进行更新调用.

那么大部分都会有一个疑问? --- 声明周期去哪里了呢?

上方的提示已经说明了 , Effect 可以当做 三个声明周期的组合, 那么我们可以利用 Effect 来模拟实现下声明周期.

componentDidMount:

如果我们把第二个参数变为空数组的话就可以实现这个同效果了.

useEffect(() => {
  console.log("组件加载完毕了我来执行了")
}, []);

componentDidUpdate:

如果我们把第二个参数不穿就是这样的.

useEffect(() => {
  console.log("状态值被更新了")
});

componentWillUnmount:

组件销毁后可以使用 useEffect 的return

useEffect(() => {
  return ()=>{
      console.log("组件销毁了我要走了")
  }
});

哈哈是不是看到这样感觉比用 class 组件写的方便很多了

hooks 使用日常最多的就是这俩个 api 剩下的我们后续再更新下, 感谢大家的阅读!