React函数式组件——useState用法简介

18,314 阅读3分钟

State在组件式编程里的基本用处

state是一个组件所包含的状态信息,所谓“状态”,就是该组件任意时刻都存放的各种数据。 state最重要的一点就是,当组件更新state时,会触发组件的重新渲染,可以认为发生了局部刷新。例如,希望在组件的div标签里显示一些动态变化的数据时,如果把这些数据作为全局变量存放,那么即便更新了这些变量,组件原先显示的数据仍然不会变,这就是因为组件并未进行重新渲染。

函数式组件的useState()

我们上手react时用的最多的就是类式组件。不过,类式组件定义和使用state虽然十分清晰,但有时其代码可能并不十分好写。尤其是我们在学习使用一些现成的图形库时,例如Antd、Antv,官方对于一些实用功能的实现全部是使用函数式组件编写的,强行将代码转成类式组件时间成本会较高。那么函数式组件如何定义和使用组件的state呢?

初始化state

类式组件中初始化state时可以直接写一句

state = {
    key1: ... ,
    key2: ...
}

进而完成类式组件state的初始化。

useState() 函数相对来讲更像是单独去针对每一个key去进行操控。例如,我们在组件中这样编码:

Child.js

import React, {useState} from "react";

const Child = () => {
    // 设置一个state属性content,初始值是字符串‘初始状态’
    // 初始值其实可以是任意类型的变量,包括字符串、boolean、列表、字典对象等等
    const [content] = useState('初始状态')
    return (
        <div>
            {content}
        </div>
    )
}
export default Child

那么我们在主页面APP.js中挂载组件Child,会获得其基本的展示:

image.png

更新state

在函数式组件中更新state应尽量按照规范调用setAttr:

import React, {useState} from "react";

const Child = () => {
    // 例如,我的属性名叫content,那么调用其set函数时尽量命名为setContent。当然,叫别的也没问题,但不太规范
    const [content, setContent] = useState('初始状态')
    return (
        // 也可以调用函数进而调用setContent,给set函数传递的参数就是你想要对其进行更新的值
        <div onClick={()=>{
            content==='初始状态' ? setContent('新的状态') : setContent('初始状态')
        }}
        >
        </div>
    )
}
export default Child

那么会获得如下效果:

20211113092242.gif

通过函数回调进行state初始化

有时我们确实希望在组件刚刚加载时才进行state初始化,例如,加载一个数据列表,但是数据列表是需要向后端请求获取的,此时就会有几种思路:

  1. 如果是由于父组件点击了什么按钮进入或渲染了这个子组件,倒不如直接在父组件写好函数先把数据获取下来,随后更新父组件状态并把这些数据以props参数传给子组件
  2. 子组件以类式组件定义,在ComponentDidMount()里执行数据获取并setState() (极不推荐!这会导致两次子组件挂载)
  3. 子组件函数式组件定义,提前定义好getData函数,直接返回获取到的data 针对函数式组件,我确实曾经采用过第三点Tip。

大致编码方式如下:

Child.js

import axios from "axios";
import React, {useState} from "react";

const Child = () => {
    const getInit = () => {
        axios(url='xxxx', method='POST', 其他属性...).then(
            request=>{
                得到服务器响应怎么处理
                return request.data
            },
            error=>{
                alert(error)
                return 一些自定义的错误信息
            }
        )
    }
    const [content, setContent] = useState(getInit)
    

    return (
        // 也可以调用函数进而调用setContent,给set函数传递的参数就是你想要对其进行更新的值
        <div>
            {content}
        </div>
    )
}
export default Child