Skip to content

ReactHooks 之 useState

React 以前都是以类来实现,新版本实现是以函数来实现。React 现在重点以函数为主,函数是 React 的第一公民

  • 利用函数不用在改变 this 指针

useState

  • 它的主要作用就是保存状态,他接受一个参数就是默认值,它返回一个数组,数组第一个就是数据,第二个就是改变数据的方法

  • 改变数据的方法里面的参数是函数,函数必须有 return

javascript
import React, { useState } from "react";
const APP = () => {
  const [name, setname] = useState("首页");
  function changename() {
    setname(() => {
      let name = "首页";
      return name + parseInt(10 * Math.random());
    });
  }
  return (
    <div>
      <span>{name}</span>
      <button onClick={changename}>点击修改</button>
    </div>
  );
};

export default APP;

useState 注意的四个方面

组件会重新执行 避免死循环

javascript
import { useState } from "react";

function FunctionPage() {
  const [count, setCount] = useState(0);
  setCount(count + 1);
  return (
    <div>
      <h1>FunctionPage</h1>
    </div>
  );
}

export default FunctionPage;

注意

你这样做 代码会无限循环,因为只要数据更新,它就会重新执行,重新执行的时候又会执行 setCount(count + 1);所以会无限循环

异步执行

  • 错误写法
javascript
import { useState } from "react";

function FunctionPage() {
  const [count, setCount] = useState(0);
  const handleClick = () => {
    setCount(count + 1);
    setCount(count + 1);
    setCount(count + 1);
    setCount(count + 1);
    console.log("点击测试结果", count);
  };
  return (
    <div>
      <div>结果是{count}</div>
      <button onClick={handleClick}>点击我</button>
    </div>
  );
}

export default FunctionPage;

注意

你这样写的时候,你会发现 count 只会加 1,因为 setCount 是异步的,它会先执行完所有的 setCount,然后再执行 console.log("点击测试结果", count);所以 count 只会加 1

  • 正确写法
javascript
import { useState } from "react";

function FunctionPage() {
  const [count, setCount] = useState(0);
  const handleClick = () => {
    setCount((count) => count + 1);
    setCount((count) => count + 1);
    setCount((count) => count + 1);
    setCount((count) => count + 1);
    setCount((count) => {
      console.log("结果是" + count);
      return count;
    });
  };
  return (
    <div>
      <div>结果是{count}</div>
      <button onClick={handleClick}>点击我</button>
    </div>
  );
}

export default FunctionPage;

注意

在开发模式和严格模式下你会发现 console 会执行了两次,这是因为 React 会在每次渲染后执行 useEffect,所以会执行两次,但是生产模式下就不会执行两次,要是想去掉直接在 main.jsx 里面去掉<StrictMode>就可以了

缓存

如果在短时间内大量多次频繁的渲染数据,它渲染数据仅仅会执行一次,因为它是缓存了

javascript
import { useState } from "react";

function FunctionPage() {
  const [count, setCount] = useState(0);
  console.log("组件渲染");
  const handleClick = () => {
    setCount((count) => count + 1);
    setCount((count) => count + 1);
    setCount((count) => count + 1);
    setCount((count) => count + 1);
    setCount((count) => {
      console.log("结果是" + count);
      return count;
    });
  };
  return (
    <div>
      <div>结果是{count}</div>
      <button
        onClick={() => {
          handleClick();
        }}
      >
        点击我
      </button>
    </div>
  );
}

export default FunctionPage;

注意

  1. 你会发现 console.log("组件渲染")只执行了一次,因为它是缓存了
  • 第二种不适用 useState 的话 它没有缓存了
javascript
import { useState } from "react";

function FunctionPage() {
  const [count, setCount] = useState(0);
  let x = 100;
  const handleClick = () => {
    setCount((count) => {
      count += 1;
      x += 1;
      console.log(`count:${count}那么x:${x}`);
      return count;
    });
  };
  return (
    <div>
      <div>结果是{count}</div>
      <button
        onClick={() => {
          handleClick();
        }}
      >
        点击我
      </button>
    </div>
  );
}

export default FunctionPage;

警告

在这里面你会发现 x 永远是 101

函数内部使用

注意

你要是把 useState 现在函数外面,是不可以的. 它会直接报错