当前位置:   article > 正文

React Hook -- useState_react hook usestate

react hook usestate

在编写页面时,我们需要将后端传过来的数据显示到指定页面上。自然而然我们可以想到可以用多个变量保存数据,然后放到页面指定位置显示数据。那问题来了,这些“状态”变量值保存呢?

有的小伙伴可能会说,可以用 var 、const 、let 来定义变量。是的,它们确实可以定义变量,但是随之又会有新的问题出现–变量改变后,我们想让页面重新渲染,显然它们是做不到的!

所以这次"主角"-- useState 出现了。

我可以简单认为 useState 可以定义变量,且这些变量改变后,页面也会随之重新渲染。

好了,进入正题。

1、useState 返回值

const [state, setState] = useState(initialState);
  • 1

useState 返回一个长度为2的数组。大部分我们是这样定义属性值变量的。如下

const [key, setKey] = useState(0);
  • 1

useState 既然返回的是一个数组,我们可以这样写:

const keyArr = useState(0);
const key = keyArr[0]; // 变量
const setKey = keyArr[1]; // 改变变量的函数
  • 1
  • 2
  • 3

这种写法显然太麻烦了,所以也很少有人用。之所以聊这中写法,其实想让小伙伴理解 useState 的返回值的类型。
如果还有对 ES6 解构赋值不太了解的小伙伴,可以去 传送门

2、useState 用法

举例说明

import { useState } from 'react';

const Counter = () => {
    const [count, setCount] = useState(0);

  	// 方法一
    function handleClick() {
        setCount(count + 1);
    }
  
  	// 方法二
    function handleClickFn() {
        setCount((prevCount) => {
            return prevCount + 1;
        });
    }
    return (
        <>
            Count: {count}
            <button onClick={handleClick}>+</button>
            <button onClick={handleClickFn}>+</button>
        </>
    );
}

export default Counter;
  • 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

我们通过 useState 定义了一个状态值变量:count,其初始值为:0
同时,还定义了一个用于改变 count 变量的函数:setCount

假如,我们想利用先前的 count 来计算(count + 1)新的 count 值,我们有两种方法实现,如上。
正常情况下,这两种方法没什么区别,都能改变变量的值,让页面重新渲染。

其实,这两种方法还是有点区别的,这也是前端面试经常问到的。如下

import { useState } from 'react';

const Counter = () => {
    const [count, setCount] = useState(0);
  
		// 方法一
    function handleClick() {
        setCount(count + 1);
        setCount(count + 1);
    }
  
  	// 方法二
    function handleClickFn() {
        setCount((prevCount) => {
            return prevCount + 1;
        });
        setCount((prevCount) => {
            return prevCount + 1;
        });
    }
    return (
        <>
            Count: {count}
            <button onClick={handleClick}>Click</button>
            <button onClick={handleClickFn}>ClickFn</button>
        </>
    );
}

export default Counter;
  • 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

当我们点击 Click 按钮时,发现 count 每次只增加 1;
当我们点击 ClickFn 按钮时,发现 count 每次却增加 2;

这是因为当我们使用一个新的 state 更新 count 值,如果多次频繁调用 useState,react 为了提高性能,它将多次 setCount 合并为最后一次调用。所以,点击 Click 按钮时,count 每次只增加 1;

当我们使用函数式方法更新 state时,因为形参 preCount 永远拿到的都是最新的 count 值,而且它也不会将多次 setCount 合并调用。所以,点击 ClickFn 按钮时,count 每次增加 2;

如果你想定义多个变量,可以:

const [count, setCount] = useState(0);
const [value, setValue] = useState("你好,世界!");
const [visible, setVisible] = useState(false);

  • 1
  • 2
  • 3
  • 4

如果变量过多,我们也可以自定义 Hook – useSetState

/**
 * 自定义Hook--useSetState
 * @description 用法和Class组件的setState()类似
 */
import { useCallback, useState } from 'react';
const useSetState = (
  initialState = {},
)=> {
  const [state, setState] = useState(initialState);
  const setMergeState = useCallback((patch) => {
    setState((prevState) => ({ 
      ...prevState,
      ...(typeof patch === "function" ? patch(prevState) : patch),
    }));
  }, []);
  return [state, setMergeState];
};
export default useSetState;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

3、补充

我们知道 useState 的形参 initialState 可以是的 字符串、数组、布尔值…类型,当它是一个函数时,在每次状态值或者属性值发生改变时,函数里的代码是否也会重新执行?

const [state, setState] = useState(initialState);
  • 1
const Counter = () => {
    const [count, setCount] = useState(() => {
        const obj = JSON.parse(bigJsonData); // 昂贵操作
        return obj.count;
    });

    ...
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

答案是肯定不会重新执行的。

每当 React 重新渲染组件时,都会执行useState(initialState)。如果初始状态是(数字,布尔值等),则不会有性能问题。
当初始状态需要昂贵的性能方面的操作时,可以通过为useState(functionCallback)提供一个函数来返回初始值,functionCallback 仅会在初次渲染时执行,在后续的渲染将不会再执行。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/660916
推荐阅读
相关标签
  

闽ICP备14008679号

        
cppcmd=keepalive&