0
点赞
收藏
分享

微信扫一扫

使用 State Hook

前文介绍了如下的Hooks例子 icon-default.png?t=LBL2https://blog.csdn.net/qq_39606853/article/details/122283215?spm=1001.2014.3001.5501

import React, { useState } from 'react';

function Example() {
  // 声明一个叫 "count" 的 state 变量
  const [count, setCount] = useState(0);

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

我们将通过将这段代码与一个等价的 class 示例进行比较来开始学习 Hook。

Class的例子

如果使用class组件,以下的代码会看起来比较熟悉

class Example extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }

  render() {
    return (
      <div>
        <p>You clicked {this.state.count} times</p>
        <button onClick={() => this.setState({ count: this.state.count + 1 })}>
          Click me
        </button>
      </div>
    );
  }
}

一开始state是{count: 0},当用户点击按钮后调用this.setState( )把state.count增加1。

Hooks和function组件

提醒一下,React里的function组件是这么写的

const Example = (props) => {
  // 你可以在这使用 Hook
  return <div />;
}

或是这样:

function Example(props) {
  // 你可以在这使用 Hook
  return <div />;
}

你之前可能就知道了这些都是无状态的组件。我们现在引入在这些组件里增加state的能力,所以我们更喜欢叫它function组件。

Hooks不能在class组件内部工作。但是你可以使用它替代class组件。

什么是Hooks

在我们新的例子首先导入useState

import React, { useState } from 'react';

function Example() {
  // ...
}

什么是一个Hook?一个Hook就是一个特殊的方法可能让你"勾入"React的特性里。比如,useState是一个Hook用来让你在function组件里增加React的state。之后我们将会学习一些其他的Hooks。

什么时候使用Hook?如果你想写一个function组件并在其中增加一些state,之前你只能把它改为class组件的形式,现在你可以在function组件里用Hook来实现增加state的功能。现在让我们开始实现它。

声明一个State变量

在一个class组件里,我们通过在构造函数里传入{ count: 0 }给this.setState( )把count设为0。

class Example extends React.Component {
constructor(props) {
  super(props);
  this.state = {
    count: 0
  };
}

在函数组件中,我们没有 this,所以我们不能分配或读取 this.state。我们直接在组件中调用 useState Hook:

import React, { useState } from 'react';

function Example() {
// 声明一个叫 “count” 的 state 变量
const [count, setCount] = useState(0);

调用useState是干了啥?它声明了一个state变量。这个变量叫count,我们也可以命名成任意别的名字,比如banana。这是一种在方法调用之间保存值的方法——useState是一个新的完全可以用来替代class组件里的this.state的方式。一般来说,变量在方法调用结束后消失,但state变量能被React保存住。

我们给useState传递什么参数?useState( )唯一的参数就是初始状态。不像在class组件里,状态不是必须为一个对象。我们可以设为一个数字或者字符串都可以。在例子中,我们仅仅期望当用户点击后反映出一个数字来,所以传递0给初始状态(如果我们想要两个不同的state变量,可以调用useState两次)。

useState返回什么?它返回了一对值——当前的状态和更新状态的方法。这就是我们写const [count, setCount] = useState()的原因。和class组件里的this.state.count以及this.setState是类似的,除了你是一下子获得它们俩的。

现在我们知道了useState干了啥,我们的例子就变得更有意思了

import React, { useState } from 'react';

function Example() {
// 声明一个叫 "count" 的 state 变量
const [count, setCount] = useState(0);

我们声明了一个count状态变量,把它设为0。React将会在重复渲染中记住它,并把最新的值返回给我们的方法。如果我们想更新它,我们可以调用setCount。

读取状态

当我们想要在class组件显示当前计数值的时候,我们读取this.state.count

<p>You clicked {this.state.count} times</p>

在函数中,我们可以直接用 count:

<p>You clicked {count} times</p>

更新状态

在class组件里,我们通过调用this.setState( )来更新state。

<button onClick={() => this.setState({ count: this.state.count + 1 })}>
   Click me
</button>

在函数中,我们已经有了 setCount 和 count 变量,所以我们不需要 this:

<button onClick={() => setCount(count + 1)}>
   Click me
</button>

总结

现在让我们来仔细回顾一下学到的知识,看下我们是否真正理解了。

import React, { 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>
  );
}
  • 第1行:我们从React里导入了useState这个Hook。它可以让我们在function组件里保持住内部state。

  • 第4行:在Example组件内部,我们通过调用useState声明了一个新的state变量。它返回了一对值。count反映了按钮点击的次数。我们传递给useState唯一参数就是state的初始值。第二个返回的是更新state的方法,命名为setState。

  • 第9行:当用户点击时,我们调用setCount传递给一个新的值。React将会重新渲染Example组件,把新的count值传递给它。

好像很多的内容。别急!如果你发现你迷失了,再从上往下看一眼上面的代码。一旦你尝试忘掉class组件里的state用法并用新鲜的眼光扫视这些代码,你会发现很有趣。

提示:方括号有什么用?

你可能注意到我们用方括号定义了一个 state 变量

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

等号左边名字并不是 React API 的部分,你可以自己取名字:

const [fruit, setFruit] = useState('banana');

这种 JavaScript 语法叫数组解构。它意味着我们同时创建了 fruit 和 setFruit 两个变量,fruit 的值为 useState 返回的第一个值,setFruit 是返回的第二个值。它等价于下面的代码:

var fruitStateVariable = useState('banana'); // 返回一个有两个元素的数组
var fruit = fruitStateVariable[0]; // 数组里的第一个值
var setFruit = fruitStateVariable[1]; // 数组里的第二个值

当我们使用 useState 定义 state 变量时候,它返回一个有两个值的数组。第一个值是当前的 state,第二个值是更新 state 的函数。使用 [0] 和 [1] 来访问有点令人困惑,因为它们有特定的含义。这就是我们使用数组解构的原因。

提示:使用多个 state 变量

将 state 变量声明为一对 [something, setSomething] 也很方便,因为如果我们想使用多个 state 变量,它允许我们给不同的 state 变量取不同的名称:

function ExampleWithManyStates() {
// 声明多个 state 变量
const [age, setAge] = useState(42);
const [fruit, setFruit] = useState('banana');
const [todos, setTodos] = useState([{ text: '学习 Hook' }]);

在上面的组件里,我们有age、fruit、todos这些state,我们可以单独的来更新它们。

function handleOrangeClick() {
   // 和 this.setState({ fruit: 'orange' }) 类似
   setFruit('orange');
}

不是非用多个state变量不可的。State变量可以为一个对象或者数组,这样你可以把相关的内容组织好。但是不像class组件里的this.setState,更新一个state变量永远只会更新它而不是合并它。

举报

相关推荐

0 条评论