React提高09 Hooks

本文详细介绍了React Hooks的引入原因、使用规定以及内置Hooks的详细用法,包括useState、useEffect的基础和高级应用,如手动合并状态、延迟初始化、避免重复渲染等。通过实例解析了Hooks如何提升代码复用、组件划分和性能优化,同时强调了正确的Hooks使用规范,以避免潜在的bug。此外,还探讨了如何在更新函数中获取当前渲染的最新值,以及如何使用useMemo和useCallback进行性能优化。
摘要由CSDN通过智能技术生成

React Hooks是V16.8的新特性,是一个向后兼容的新特性(不会引入破坏性的改变)。

Hook是一种能够“侵入”React的函数组件的状态和生命周期特性的函数。Hook不能用在class中,因为Hook的目的就是你能够抛弃class来使用React

React提供了一些内嵌的Hooks,例如useState。也可以创建自己的Hook,达到在不同的组件间复用有状态的行为。

引入的原因

实现比现有方案(HOC/Render Props)更优雅的代码复用,为纯组件引入状态,能够将组件划分为更细的粒度。

  1. 现有的React的状态组件复用方式(高阶组件、Render Props)有各自的问题, 而Hooks可以优雅的(不改变组件层次)实现代码复用
  2. Hooks可以将组件根据功能,将组件划分为更小的粒度,便于调试、测试和维护
  3. Hooks可以不使用Class来编写组件,提高代码性能,降低React的使用难度

Hooks的使用规定

(1)只在最顶层调用Hooks,不要在内部循环、条件语句或嵌套函数中调用Hooks(这是因为React是通过多个Hooks的调用顺序来确定多个useState中状态变量的对应关系),如果想要有条件的运行一个useEffect,可以将条件判断放在Hook内部

useEffect(function persistForm() {
  // ? We're not breaking the first rule anymore
  if (name !== '') {
    localStorage.setItem('formData', name);
  }
});

(2)只在React函数中调用Hooks,不在普通的JavaScript函数中调用

可以通过ESLint的eslint-plugin-react-hooks插件来检查、规范Hooks的使用,避免不规范的使用而导致的bug。

安装:

npm install eslint-plugin-react-hooks -D

ESLint的配置文件:

{
  "plugins": [
    // ...
    "react-hooks"
  ],
  "rules": {
    // ...
    "react-hooks/rules-of-hooks": "error"
  }
}

将来这个插件会默认集成在Create React App和类似工具中。

内置Hooks

React提供了一系列内置Hooks,共分为两大类,基础Hook和附加Hook。

基础Hook包括:

  • useState
  • useEffect
  • useContext

附加Hook包括:

  • useReducer
  • useCallback
  • useMemo
  • useRef
  • useImperativeHandle
  • useLayoutEffect
  • useDebugValue

useState

1 useState - 基础用法

import { useState } from 'react';
const [count, setCount] = useState(0);

内置的useState用来为纯组件添加状态变量和更新方法,可以认为是this.statethis.setState的简化版,以数组的形式获取状态变量,返回数组中的第一个项是一个状态,第二个是更新方法,useState接受的参数是初始值。

当再次渲染时,React会在函数组件中获取count的最新值,如果想要更新count可以调用setCount

2 useState - 手动合并

注意:useState不会自动合并更新对象,所以需要手动进行合并,举个例子,在class组件中:

class Test extends React.Component {
  state = { a: 1, b: 2, };

  render() {
    console.log(this.state);
    return (
      <div>
        <button onClick={() => this.setState({ a: 100 })}>click</button>
      </div>
    );
  }
}

点击按钮,setState会自动将对象合并,打印结果是{a: 100, b: 2}

而在使用Hooks的组件中中:

function Test() {
  const [state, setState] = useState({ a: 1, b: 2 });
  console.log(state);
  return (
    <div>
      <button onClick={() => setState({ a: 100 })}>click</button>
    </div>
  );
}

useState在更新时不会将对象合并,所以打印的结果是{a: 100}&#x

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值