zl程序教程

您现在的位置是:首页 >  其他

当前栏目

React的State Hook用法详解!

2023-03-20 14:51:58 时间
一、State Hook是啥?

State Hook 就是指 useState 这个特殊函数,让你不用编写class,就可以使用state特性,换言之就是让 函数组件 拥有 state 特性,对数据进行动态更新。

二、class中的state

动态改变数据,譬如一个计数器组件,class组件中实现方式如下:

class Example extends React.Component {
    constructor(props) {
        super(props);
        // 只能在构造函数中初始化state
        this.state = {
            count: 0
        };
    }

    // 只能调用 this.setState 方法来更新 count 值
    render() {
        return (
            <div>
                <p>You clicked {this.state.count} times</p>
                <button onClick={() => this.setState({ count: this.state.count + 1 })}>
                    Click me
                </button>
            </div>
        );
    }
}
三、useState怎么用?
1、简单实例

在函数组件中,用 useState 实现计数器功能,跟上面class实现一样的功能。

import React, { useState } from 'react';

function Example() {
    // 声明 `count` 的 state 变量 和 用于改变 `count` 的setCount方法;
    const [count, setCount] = useState(0);
    // 上面这一句是js中数组解构语法,其实它等同于下面这几句:
    //   var countStateVariable = useState(0); // 返回一个有两个元素的数组
    //   var count = countStateVariable[0]; // 数组里的第一个值
    //   var setCount = countStateVariable[1]; // 数组里的第二个值

    // count 和 setCount 是函数内部的变量和方法,可直接访问
    return (
        <div>
            <p>You clicked {count} times</p>
            <button onClick={() => setCount(count + 1)}>
                Click me
            </button>
        </div>
    );
}
2、可使用多个state
function ExampleWithManyStates() {
  // 声明多个 state 变量,且他们都是相互独立的
  const [age, setAge] = useState(42);
  const [fruit, setFruit] = useState('banana');
  const [todos, setTodos] = useState([{ text: '学习 Hook' }]);
3、函数式更新

setCount( c => c +1 ) 这种方式就是函数式更新,确保了 count 更新总是建立在最新的数据上,让你从 count 的管理中解脱出来。如下实例,一个计数器,count 数值的变化,永远基于最新数值,让你不用去管理count。

function Counter({ initialCount }) {
    const [count, setCount] = useState(initialCount);
    return (
        <>
            Count: {count}
            <button onClick={() => setCount(initialCount)}>Reset</button>
            <button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>
            <button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
        </>
    );
}

备注:此功能用在 useEffect 中,会非常方便。

4、惰性初始化

useState 的初始化,可以通过传入函数的方式进行,适用于复杂计算后的结果。

const [state, setState] = useState(() => {
    const initialState = someExpensiveComputation(props);
    return initialState;
});
5、跳过 state 更新

调用 useState 的更新方法来更新state,如果新 state 数值跟之前是一样的,那么组件会跳过子组件的渲染和 useEffect 的调用。

四、合并更新

class组件中的 setState 会自动合并更新 state 对象。useState 可通过 展开运算符Object.assignuseReducer 来合并更新对象。

1、展开运算符
const [state, setState] = useState({});
setState(prevState => {
    return { ...prevState, ...updatedValues };
});
2、Object.assign
const [state, setState] = useState({});
setState(prevState => {
    return Object.assign(prevState, updatedValues);
});
3、useReducer

更适合用于管理包含多个子值的 state 对象。

五、参考链接