React Native 状态管理 - useState

前言

在传统的移动端开发中,页面的展示和数据是分开管理的。比如在 iOS 中如果我们要显示一个标题的话,会使用下面这种命令式 UI 的方式去实现,如 UIKit 中的控件:

ini 复制代码
// 先设置 UILabel 的样式
let titleLabel = UILabel(frame: .zero)
titleLabel.textColor = .black
self.titleLabel = titleLabel

// 然后加载完数据之后,再去设置内容
self.titleLabel.text = mode.title

这样实现存在一个问题就是代码分离,实现完控件之后我们还需要等网络数据回来之后再去修改控件的展示。

使用了状态管理的声明式 UI 就解决了上面存在的问题。我们只负责实现完控件之后将其和状态管理的变量绑定,之后我们只需要操作状态管理的变量即可,控件的样式会自动去更新。在 React Native 中,useState 就是来进行状态管理的。

首先,我们来看下它是如何使用的。

useState 的使用

第一步,我们需要导入 React 来使用 useState:

javascript 复制代码
import { useState } from 'react';

接下来,在自定义的组件中去使用它:

javascript 复制代码
export default function Counter() {
  const [counter, setCounter] = useState(1);

  function counterIncreate() {
    setCounter(counter + 1);
  }

  return (
    <>
      <View style={{ width: '100%', height: '200rpx' }}>
        <Text style={{ width: '100rpx', height: '30rpx' }}>{`数量:${counter}`} </Text>
        <TouchableOpacity style={{ width: '100rpx', height: '60rpx' }} onPress={() => counterIncreate()}>
          <Text style={{ width: '50rpx', height: '30rpx' }}>增加</Text>
        </TouchableOpacity>
      </View>
    </>
  );
}

上面的代码绘制了两个组件,一个是显示当前数量的文本组件,一个是增加数量的按钮组件。然后声明了一个 counterIncreate() 函数用来更新 counter 的值。 最后将 counter 变量与显示数量的文本组件进行绑定。

核心代码就是下面的这两行:

scss 复制代码
// 组件与变量进行绑定
<Text style={{ width: '100rpx', height: '30rpx' }}>{`数量:${counter}`} </Text>
// 点击按钮的时候去修改状态变量
setCounter(counter + 1);

上面的代码运行之后,点击增加按钮,数量加1之后会自动进行渲染。

useState 函数

scss 复制代码
const [counter, setCounter] = useState(1);

通过上面的代码可以看到,useState() 接受一个任意类型的初始值,然后返回一个数组。数组包含一个状态变量,变量的初始值是函数传进去的初始值;一个状态变量对应的 set 函数。关于数组内的命名约定俗成的格式是下面这种格式:

  • xxx, setXxx xxx 为变量名。

但你修改了也不会影响状态管理的功能,比如下面的代码:

scss 复制代码
// set 命名为 setCounter1
const [counter, setCounter1] = useState(1);

function counterIncreate() {
   setCounter1(counter + 1);
}

但建议还是按照约定俗成的格式去命名。

数据的不变性

对与状态变量,是有不可变性的。我们只能通过返回的 set 函数去修改它的值。我们需要使用 const 去修饰。我们不能通过直接修改状态变量的值去更新渲染组件。比如下面的代码:

scss 复制代码
const [counter, setCounter] = useState(1);
function counterIncreate() {
  // 报错,因为 counter 是不可变的。
  counter = counter + 1;
}

即使我们用 let 修饰,虽然不会报错,但也无法进行组件状态的更新:

ini 复制代码
let [counter, setCounter] = useState(1);

function counterIncreate() {
  counter = counter + 1;
}

原因是 React Native 是在返回的 setState 函数中去处理状态更新的相关逻辑,所以 counter = counter + 1 是无法触发组件的状态更新。

如何获取当前的状态值

如果我们的需求是在更新状态的同时还要记录下当前的状态值,那么需要像下面这种方式去获取:

ini 复制代码
  function counterIncreate() {
    // counter = 1
    setCounter(counter + 1);
    const result = counter + 1;
    console.log(result); // 2
  }

如果我们这样写是无法正确的获取当前状态值的:

ini 复制代码
  function counterIncreate() {
    // counter = 1
    setCounter(counter + 1);
    const result = counter;
    console.log(result); // 1
  }

因为 counter 更像是保存的一份快照,我们调用 setCounter() 函数的时候并不会去更新 counter 的值,所以这种方式是不能正确获取的。

相关推荐
梦想的颜色4 小时前
【编程实战】AI 时代 APP 开发全栈硬核指南:技术选型 + AI 架构 + 模型落地全维度决策
python·flutter·react native·react.js·ai·桌面应用·milvus
song50115 小时前
React Native for OpenHarmony 实战:三方库 react-native-css-transformer 的鸿蒙化适配指南
css·人工智能·深度学习·react native·transformer
enjoywindstorm3 天前
移动端原生框架对比评测
react native
传奇开心果编程3 天前
【声明式UI开发实用技术学与练】第8课 状态提升与下放
学习·flutter·react native·ui·swiftui·composer
传奇开心果编程4 天前
【现代声明式UI学与练】第4课 列表渲染与 key——如何高效渲染列表、key 的作用、列表重排时的状态保持
学习·flutter·react native·ui·swiftui·android jetpack
传奇开心果编程5 天前
【现代声明式UI学与练】第7课 组件通信——父传子、子传父、跨层级通信、状态提升与 Context
学习·flutter·react native·ui·swiftui·android jetpack
500845 天前
React Native for OpenHarmony 实战:三方库 react-native-url-polyfill 的鸿蒙化适配指南
javascript·react native·react.js·性能优化·electron·harmonyos
传奇开心果编程5 天前
【现代声明式UI学与练】第9课 性能优化——渲染优化、列表优化、内存优化、启动优化
学习·flutter·react native·ui·性能优化·swiftui·android jetpack
500845 天前
React Native for OpenHarmony 实战:三方库 react-native-volume-control 的鸿蒙化适配指南
javascript·react native·react.js·electron·harmonyos
5008410 天前
React Native for OpenHarmony 实战:三方库 react-native-crypto-js 的鸿蒙化适配指南
javascript·react native·性能优化·electron·harmonyos