几种常见的React Hooks

useState

useState,让函数组件拥有了维持状态的功能。维持状态是指在函数的多次渲染之间,这个state是可以在函数中间共享的

使用方式

import React, { useState } from 'react';

const Counter = () => {
  const [count, setCount] = useState(0);
  
  return (
    <div>
      <p>{ count }</p>
      <button onClick={() => setCount(count + 1)}>点击</button>
    </div>
  )
}

export default Counter

参数解析

useState(initialState)的参数initialState是state的初始值,可以是任意类型,如字符串、数值、布尔值、对象、数组

import React, { useState } from 'react';

const Counter = () => {
  const [count, setCount] = useState(0);
  const [visible, setVisible] = useState(false);
  const [store, setStore] = useState({});
  const [list, setList] = useState([]);
  const [name, setName] = useState('xcc');
  
  return ...
}

export default Counter

useState()返回值是一个包含两个元素的数组,第一个值为state的值,为只读的,第二个是用来设置state值的

对比类组件

类组件只有一个state,通过通过对象中的不同属性来表示不同的状态,通过setState来进行更新。函数组件可以创建多个state,用来描述不同状态的值,更加语义化

类组件:

import React from 'react'

class Counter extends Component {
  constructor(props) {
    super(props)
    this.state = {
      count: 0,
      visible: false
    }
  }
 
  componentDidMount() { 
    setState({ count: 1 })
  }

  render() {
    ...
  }
}

export default Counter

函数组件:

import React, { useState } from 'react';

const Counter = () => {
  const [count, setCount] = useState(0);
  const [visible, setVisible] = useState(false);
  
  return ...
}

export default Counter

使用时需要注意的点

不要在state中存储可以通过计算得到的值

常见情况:

  1. props中传递过来的值
  2. 存储在cookie、localStorage中的值
  3. 挂载在URL参数上的值

useEffect

useEffect,用来执行一段副作用,副作用是指一段和当前执行结果无关的代码。其中代码的执行是不会影响UI的渲染

使用方式

import React, { useState, useEffect } from 'react'

const WindowSize = () => {
  const [size, setSize] = useState(null)

  useEffect(() => {
    const handleResize = () => {
      ...
    }
    window.addEventListener("resize", handleResize)
    return () => {
      window.removeEventListener("resize", handleResize)
    }
  }, [])

  return (
    ...
  )
}

export default WindowSize

参数解析

useEffect(callback, dependencies)

callback为要执行的函数,dependencies为可选的依赖项数组

几种常见的使用方式:

没有依赖项时,会在每次render后执行

useEffect(() => {})

依赖项为空数组时,会在首次render后执行

useEffect(() => {}, [])

依赖项不为空时,会在首次render后,每次依赖项数组发生改变时执行

useEffect(() => {}, [a,b,c])

组件在卸载时执行

useEffect(() => { return () => {} }, [])

对比类组件

useEffect想比类组件的生命周期,基本可以等价于ComponentDidMount、componentDidUpdate 和 componentWillUnmount这三个方法,但有不是完全相同

类组件

import React from 'react'

class WindowSize extends Component {
  constructor(props) {
    super(props)
    this.state = {
      size: null
    }
  }
 
  componentDidMount() { 
    window.addEventListener("resize", this.handleResize)
  }

  componentWillUnmount() { 
    window.removeEventListener("resize", this.handleResize)
  }

  handleResize = () => {
    ...
  }

  render() {
    ...
  }
}

export default WindowSize

函数组件:

import React, { useState, useEffect } from 'react'

const WindowSize = () => {
  const [size, setSize] = useState(null)

  useEffect(() => {
    const handleResize = () => {
      ...
    }
    // 等价于类组件中的componentDidMount
    window.addEventListener("resize", handleResize)
    // 等价于类组件中的componentWillUnmount
    return () => {
      window.removeEventListener("resize", handleResize)
    }
  }, [])

  return (
    ...
  )
}

export default WindowSize

使用时注意的点

依赖项一定要为回调函数中在使用的变量

import React, { useState, useEffect } from 'react'

const Books = ({ id }) => {
  const [list, setList] = useState([])

  useEffect(() => {
    const getList = async () => {
      const res = await getBookList({ id })
      setList(res.data)
    }
    getList()
  }, [id])

  return ...
}

export defaule Books;

依赖项要为一个常量数组,而不是一个动态数据

useEffect(() => {}, [id])

React会使用浅比较来对比依赖项是否发生改变,因此不要使用对象、数组等作为依赖项

function Todos() {
  // 这里在每次组件执行时创建了一个新数组
  const todos = [{ text: 'Learn hooks.'}];
  useEffect(() => {
    console.log('Todos changed.');
  }, [todos]);
}
posted @ 2022-11-17 17:13  小菜菜爱吃菜  阅读(116)  评论(0编辑  收藏  举报