京东-优惠雷达
新人页面
精选商品
首月0月租体验,领12个月京东PLUS
自营热卖

初探 React Hooks(一)

终遇你 1年前   阅读数 72 0

对于近期工作中使用的React Hooks进行一个总结,以及使用了Hooks的函数式组件和传统类组件的简单比较,欢迎补充、修正和探讨

useState

下面的代码是使用了useState的再简单不过的案例,定义一个数组,里面接受两个参数,第一个表示状态属性,第二个为修改属性的方法,useState中接受的参数作为状态的初始值

import { useState } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  )
}

useState的使用方法与setState基本相同,但在特性上有些许的不同,例如useState不会天生的支持async/await了,而setState是可以直接使用await的。但是通过useEffect,也的确不需要使用await来等待状态改变的操作完成了

useEffect

useEffect函数可以理解为类组件中componentDidMount、componentDidUpdate、componentWillUnmount三个生命周期函数的集合,useEffect接受两个参数,第一个参数是一个是回调函数,这是需要执行的副作用函数,第二个参数是一个依赖数组,当数组中依赖的值发生改变时,这个回调函数就会执行。

function App() {
  const [data, setData] = useState([]);

  useEffect(() => {
    const result = "后台数据"

    setData(result.data);
  }, []);   
  //依赖数组为空时,无论其他参数如何变化,只会渲染一次,通过这个特性,我们可以
  //用来模仿componentDidMount钩子
  useEffect(async () => {
     console.log("数据更新")
  }, [data]); 
  //当依赖数组中有值时,类似于componentDidUpdate钩子,且由于依赖数组的存在,我们会
  //自然而然的把针对某个参数的操作写在一处,代码更具有可读性
  
  return (
    <ul>
      {data.map(item => (
        <li key={item.objectID}>
          {item.text}
        </li>
      ))}
    </ul>
  );
}

export default App;

我们在上面的代码块中实现的componentDidUpdate钩子其实是有缺陷的,因为在初始化时这个update同样会执行,如果需要一个纯粹的只在更新时执行的函数,会产生一些问题,我们可以通过搭配useRef的方法实现这样一个纯粹的update函数

const isUpdate = useRef(false)
useEffect(()=>{
        if(isUpdate.current){
           //...
        } else {
            isUpdate.current=true
        }   
    },[data])

使用useEffect不支持像下面这样使用async直接操作否则会产生错误

useEffect(async () => {
    const result = await axios(
      'http://localhost/getData',
    );

    setData(result.data);
  }, []);  

在这里插入图片描述

报错原因官方已经说的十分详细,即useeffect的返回值只能是空或者一个函数,但我们在用async函数返回的是一个Promise对象,与react要求不符。官方建议我们直接封装一个支持async的函数在useEffect内部使用。

而官方提到的这个返回值中接受的函数,其实就是类组件中对应的componentWillUnmount生命周期函数,假如这个组件有可能发生内存泄漏,我们可以在这里清理。

发布了1 篇原创文章 · 获赞 6 · 访问量 77

注意:本文归作者所有,未经作者允许,不得转载

全部评论: 0

    我有话说: