项目目前用的React版本是 17.0.2

React Hooks是什么?

  1. Hooks是React 16.8.0版本增加的新特性/新语法
  2. 可以让你在函数组件中使用state以及其他的React特性
  3. 简单输入框,类组件和函数组件写法比较:
    • 类组件
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      /**
      * @name 类组件
      */
      import React from 'react';
      export default class Home extends React.Component {
      constructor(props) {
      super(props);
      this.state = {
      name: 'world'
      };
      }
      componentDidMount() {
      console.log('组件挂载后要做的操作')
      }
      componentWillUnmount() {
      console.log('组件卸载要做的操作')
      }
      componentDidUpdate(prevProps, prevState) {
      if (prevState.name !== this.state.name) {
      console.log('组件更新后的操作')
      }
      }
      render() {
      return (
      <div>
      <p>hello {this.state.name}</p>
      <input type="text" placeholder="input new name"
      onChange={(e) => this.setState({ name: e.target.value })}>
      </input>
      </div>
      );
      }
      }
    • 函数组件
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      /**
      * @name 函数组件
      */
      import React, { useState, useEffect } from 'react';

      export default function Home() {
      const [name, setName] = useState('world');
      return (
      <div>
      <p>hello {name}</p>
      <DemoState />
      </div>
      )
      }

      function DemoState() {
      const [n1, setN1] = useState(1)
      const [n2, setN2] = useState(2)
      const [n3, setN3] = useState(3)

      useEffect(() => {
      setN1(10)
      setN1(100)
      }, [])
      const handleClick = () => {
      setN2(20)
      setN3(30)
      }
      console.log('demo-state', n1, n2, n3)
      return <button onClick={handleClick}>click</button>
      }
    • useState相当于constructor,完成数据的初始化
    • useEffect相当于componentDidMount和componentDidUpdate两个生命周期,通过return () => {}的方式解绑生命周期,相当于componentWillUnmount周期
    • 此外还有发生在页面渲染前的useMemo相当于shouldComponentUpdate周期等,具体关系如下
  • 结论:使用hooks的函数组件,简化了很多代码,不用维护复杂的生命周期,也不用担心this的指向问题。

常用hooks

  1. State Hook
    • State Hook让函数组件也可以有state状态,并进行状态数据的读写操作
    • 语法: const [xxx, setxxx] = React.usestate(initvalue)
    • useState()说明:
      • 参数: 第一次初始化指定的值在内部作缓存
      • 返回值: 包含2个元素的数组,第1个为内部当前状态值,第2个为更新状态值的函数
    • setxxx()2种写法:
      • setxxx(newValue): 参数为非函数值,直接指定新的状态值,内部用其覆盖原来的状态值
      • setxxx(value => newValue): 参数为函数,接收原本的状态值,返回新的状态值,内部用其覆盖原来的状态值
  2. Effect Hook
    • Effect Hook让在函数组件中执行副作用操作(用于模拟类组件中的生命周期钩子)
    • React中的副作用操作:
      • 发ajax请求数据获取
      • 设置订阅/启动定时器
      • 手动更改真实DOM
    • 语法和说明:
      1
      2
      3
      4
      5
      6
      useEffect(() => {
      // 在此可以执行任何带副作用操作
      return () => { //在组件写在前执行
      // 在此做一些收尾工作,比如清楚定时器/取消订阅等
      }
      }, [stateValue]) // 如果指定的是[],回调涵数只会在第一次render()后执行
  3. Ref Hook
    • Ref Hook可以在函数组件中存储/查找组件内的标签或任意其它数据
    • 语法:const refcontainer = useRefo()
    • 作用:保存标签对象,功能与React.createRef()一样
  4. Memo Hook
    • Memo Hook用于性能优化,通过记忆值来避免在每个渲染上执⾏高开销的计算
    • 接受2个参数: 一个compute计算函数和depedencies数组
    • 语法: const memoizedResult = useMemo(compute, dependencies)
    • 例子: 仅当count发生变化时计算新的memoized值
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      function App () {
      const [ count, setCount ] = useState(0)
      const add = useMemo(() => count + 1, [count])
      return (
      <div>
      点击次数: { count }
      <br/>
      次数加一: { add }
      <button onClick={() => { setCount(count + 1)}}>点我</button>
      </div>
      )
      }