React State组件的记忆

组件通常需要根据交互更改屏幕上显示的内容。输入表单应该更新输入字段,单击轮播图上的“下一个”应该更改显示的图片,单击“购买”应该将商品放入购物车。组件需要“记住”某些东西:当前输入值、当前图片、购物车。在 React 中,这种组件特有的记忆被称为 state

学习

  • 如何使用 useState Hook 添加 state 变量
  • useState Hook 返回哪一对值
  • 如何添加多个 state 变量
  • 为什么 state 被称作是局部的

useState Hook 提供了这两个功能:

  1. State 变量 用于保存渲染间的数据。
  2. State setter 函数 更新变量并触发 React 再次渲染组件。

 添加一个 state 变量 

要添加 state 变量,先从文件顶部的 React 中导入 useState

import { useState } from 'react';

 以下是一个渲染作品文章的组件。点击 “Next” 按钮显示下一个作品并将 index 更改为 1,再次点击又更改为 2,以此类推。

import React, { useState } from 'react';
import {Button} from "antd";

const sculptureList = [
    {
        name: '云边有个小卖部',
        artist: '张嘉佳',
        description: '生命是有光的,在我熄灭以前,能够照亮你一点,就是我所有能做的了.我爱你,你要记得我',
    },
    {
        name: '去有风的地方',
        artist: '水阡墨',
        description: '2222222222222222222222222222222222222',
    },
    {
        name: '从你的全世界路过',
        artist: '张嘉佳',
        description: '33333333333333333333',
    },
];
const App:React.FC = () => {
    const [index, setIndex] = useState(0);
    const handleClick=()=> {
        setIndex(index + 1);
    }
    let sculpture = sculptureList[index];
    return (
        <>
            <Button type="primary" onClick={handleClick}>
                Next
            </Button>
            <h2>
                <i>{sculpture.name} </i>
                来自 {sculpture.artist}
            </h2>
            <h3>
                ({index + 1} of {sculptureList.length})
            </h3>
            <hr/>
            <p>
                {sculpture.description}
            </p>
        </>
    );
}
export default App

剖析 useState

useState 的唯一参数是 state 变量的初始值。在这个例子中,index 的初始值被useState(0)设置为 0

每次你的组件渲染时,useState 都会给你一个包含两个值的数组:

  1. state 变量 (index) 会保存上次渲染的值。
  2. state setter 函数 (setIndex) 可以更新 state 变量并触发 React 重新渲染组件。

以下是实际发生的情况:

const [index, setIndex] = useState(0);
  1. 组件进行第一次渲染。 因为你将 0 作为 index 的初始值传递给 useState,它将返回 [0, setIndex]。 React 记住 0 是最新的 state 值。
  2. 你更新了 state。当用户点击按钮时,它会调用 setIndex(index + 1)。 index 是 0,所以它是 setIndex(1)。这告诉 React 现在记住 index 是 1 并触发下一次渲染。
  3. 组件进行第二次渲染。React 仍然看到 useState(0),但是因为 React 记住 了你将 index 设置为了 1,它将返回 [1, setIndex]
  4. 以此类推!

赋予一个组件多个 state 变量 

你可以在一个组件中拥有任意多种类型的 state 变量。该组件有两个 state 变量,一个数字 index 和一个布尔值 showMore,点击 “Show Details” 会改变 showMore 的值:

import React, { useState } from 'react';
import {Button} from "antd";

const sculptureList = [
    {
        name: '云边有个小卖部',
        artist: '张嘉佳',
        description: '生命是有光的,在我熄灭以前,能够照亮你一点,就是我所有能做的了.我爱你,你要记得我',
    },
    {
        name: '去有风的地方',
        artist: '水阡墨',
        description: '2222222222222222222222222222222222222',
    },
    {
        name: '从你的全世界路过',
        artist: '张嘉佳',
        description: '33333333333333333333',
    },
];
const App:React.FC = () => {
    const [index, setIndex] = useState(0);
    const [showMore, setShowMore] = useState(false);

    const handleClick=()=> {
        setIndex(index + 1);
    }
    const handleMoreClick=()=> {
        setShowMore(!showMore);
    }

    let sculpture = sculptureList[index];
    return (
        <>
            <Button type="primary" onClick={handleClick}>
                Next
            </Button>
            <h2>
                <i>{sculpture.name} </i>
                来自 {sculpture.artist}
            </h2>
            <h3>
                ({index + 1} of {sculptureList.length})
            </h3>
            <hr/>
            <Button type="default" onClick={handleMoreClick}>
                {showMore ? 'Hide' : 'Show'} details
            </Button>
            <p>
                {showMore && <p>{sculpture.description}</p>}
            </p>
        </>
    );
}
export default App

State 是隔离且私有的 

State 是屏幕上组件实例内部的状态。换句话说,如果你渲染同一个组件两次,每个副本都会有完全隔离的 state!改变其中一个不会影响另一个。

在这个例子中,之前的 Gallery 组件以同样的逻辑被渲染了两次。试着点击每个画廊内的按钮。你会注意到它们的 state 是相互独立的:

import React, { useState } from 'react';
import {Button, Col, Row} from "antd";

const sculptureList = [
    {
        name: '云边有个小卖部',
        artist: '张嘉佳',
        description: '生命是有光的,在我熄灭以前,能够照亮你一点,就是我所有能做的了.我爱你,你要记得我',
    },
    {
        name: '去有风的地方',
        artist: '水阡墨',
        description: '2222222222222222222222222222222222222',
    },
    {
        name: '从你的全世界路过',
        artist: '张嘉佳',
        description: '33333333333333333333',
    },
];

const Gallery=()=>{
    const [index, setIndex] = useState(0);
    const [showMore, setShowMore] = useState(false);
    const handleClick=()=> {
        setIndex(index + 1);
    }
    const handleMoreClick=()=> {
        setShowMore(!showMore);
    }
    
    let sculpture = sculptureList[index];
    return (
        <>

            <Button type="primary" onClick={handleClick}>
                Next
            </Button>
            <h2>
                <i>{sculpture.name} </i>
                来自 {sculpture.artist}
            </h2>
            <h3>
                ({index + 1} of {sculptureList.length})
            </h3>
            <hr/>
            <Button type="default" onClick={handleMoreClick}>
                {showMore ? 'Hide' : 'Show'} details
            </Button>
            <p>
                {showMore && <p>{sculpture.description}</p>}
            </p>
        </>
    );
}

const App:React.FC = () => {
    return(
        <div>
            <Row>
                <Col span={12}><Gallery/></Col>
                <Col span={12}><Gallery/></Col>
            </Row>
        </div>
    )
}
export default App

这就是 state 与声明在模块顶部的普通变量不同的原因。 State 不依赖于特定的函数调用或在代码中的位置,它的作用域“只限于”屏幕上的某块特定区域。你渲染了两个 <Gallery /> 组件,所以它们的 state 是分别存储的。

与 props 不同,state 完全私有于声明它的组件。父组件无法更改它。这使你可以向任何组件添加或删除 state,而不会影响其他组件。

摘要

  • 当一个组件需要在多次渲染间“记住”某些信息时使用 state 变量。
  • State 变量是通过调用 useState Hook 来声明的。
  • Hook 是以 use 开头的特殊函数。它们能让你 “hook” 到像 state 这样的 React 特性中。
  • Hook 可能会让你想起 import:它们需要在非条件语句中调用。调用 Hook 时,包括 useState,仅在组件或另一个 Hook 的顶层被调用才有效。
  • useState Hook 返回一对值:当前 state 和更新它的函数。
  • 你可以拥有多个 state 变量。在内部,React 按顺序匹配它们。
  • State 是组件私有的。如果你在两个地方渲染它,则每个副本都有独属于自己的 state。

文章及例子是参考React官方文档教程,不同的是我这里使用TS来写,开发环境:React+ts+antd

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值