You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从存储更新React Native函数式组件State并解决测试渲染异常

问题原因及解决方案

核心问题有三个,同时涉及组件写法和测试写法:

    1. JSON序列化丢失类实例特征:你通过JSON.stringify存储MyClass实例,读取后JSON.parse得到的是普通JS对象,不是MyClass类的实例,没有getTitle()、getValue()方法,调用后返回undefined,所以渲染为空。
    1. 组件异步逻辑位置错误:直接在函数组件顶层调用异步加载逻辑,会导致组件每次重渲染都重复触发加载,正确写法应该放在useEffect空依赖回调中,仅挂载时执行一次。
    1. 测试没有等待异步逻辑执行完成:setup是异步函数,你没有await就直接渲染组件,且渲染后没有等待状态更新就调用debug(),拿到的是首次渲染的初始状态结果。

修复后的组件代码

import React, { useState, useEffect } from "react";
import { ReactElement } from "react-native/node_modules/@types/react";
import { Text, View } from "react-native";
import MyClass from "./MyClass";
import AsyncStorage from "@react-native-async-storage/async-storage";

export default function FunCompWithState(): ReactElement {
  const [myClass, setMyClass] = useState<MyClass>(new MyClass());

  // 放到useEffect中,仅挂载时执行一次
  useEffect(() => {
    async function load() {
      const data = await loadFromStorage();
      if (data) {
        // 把普通对象转成MyClass实例
        const instance = new MyClass();
        instance.setTitle(data.title);
        instance.setValue(data.value);
        setMyClass(instance);
      }
    }
    load();
  }, []);

  return (
    <View>
      <Text>{myClass.getTitle()}</Text>
      <Text>{myClass.getValue()}</Text>
    </View>
  );
}

async function loadFromStorage(): Promise<Record<string, any> | null> {
  const jsonValue = await AsyncStorage.getItem("@main.myClass");
  console.log(jsonValue);
  if (jsonValue != null) {
    return JSON.parse(jsonValue);
  }
  return null;
}

修复后的测试代码

import * as React from "react";
import { render, waitFor } from "@testing-library/react-native";
import FunCompWithState from "../FunCompWithState";
import MyClass from "../MyClass";
import AsyncStorage from "@react-native-async-storage/async-storage";

async function setup() {
    const storedClass = new MyClass();
    storedClass.setTitle("Stored Class");
    storedClass.setValue(8);
    await AsyncStorage.setItem("@main.myClass", JSON.stringify(storedClass));
}

// 测试用例改为异步函数
it("Render FunCompWithState", async () => {
  // 等待初始化存储完成
  await setup();

  const { debug, getByText } = render(<FunCompWithState />);
  // 等待异步状态更新完成,确认目标文本渲染后再debug
  await waitFor(() => {
    expect(getByText("Stored Class")).toBeTruthy();
    expect(getByText("8")).toBeTruthy();
  });
  debug();
});

内容的提问来源于stack exchange,提问作者Austin Brown

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 21:24:01