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

React Native中如何让onPress调用的函数返回字符串并渲染?

解决方案:实现用户名更新的反馈消息展示

1. 改造writeUserName为异步Promise函数

原函数中的Firebase查询是异步操作,无法直接同步返回结果,因此需要将其改为返回Promise的形式,通过resolve传递成功消息、reject传递错误消息:

修改后的useWriteDb.js:

import { db } from "../model/config";
import { get, ref, child, update } from "firebase/database";

function writeUserName(userId, username) {
  return new Promise((resolve, reject) => {
    // 同步校验逻辑
    if (!username) {
      reject("用户名不能为空");
      return;
    }
    if (username.length > 20) {
      reject("用户名过长(最多20字符)");
      return;
    }
    if (username.length < 3) {
      reject("用户名过短(最少3字符)");
      return;
    }

    // 异步查询用户名是否重复
    get(child(ref(db), "users/"))
      .then((snapshot) => {
        if (snapshot.exists()) {
          const users = snapshot.val();
          for (const userKey in users) {
            if (users[userKey].username === username) {
              reject("用户名已存在");
              return;
            }
          }
          // 更新数据库
          update(ref(db, "users/" + userId), { username })
            .then(() => resolve("用户名更新成功"))
            .catch(err => reject(`更新失败:${err.message}`));
        } else {
          reject("用户数据不存在");
        }
      })
      .catch(err => reject(`查询失败:${err.message}`));
  });
}

function retriveUserData(userId) {
  get(child(ref(db), "users/"))
    .then((snapshot) => {
      if (snapshot.exists()) {
        console.log(snapshot.val());
      } else {
        console.log("No data available");
      }
    })
    .catch((error) => {
      console.error(error);
    });
}

export { writeUserName, retriveUserData };

2. 在EditProfileScreen中处理异步调用并展示反馈

添加状态存储反馈消息,将点击事件改为异步函数,处理Promise的成功/失败结果:

修改后的EditProfileScreen.js:

import { View, Text, TextInput, TouchableOpacity } from "react-native";
import React, { useState } from "react";

import styles from "./styles";
import useAuth from "../../hooks/useAuth";
import { writeUserName } from "../../hooks/useWriteDb";

const EditProfileScreen = ({ navigation }) => {
  const [username, setUserName] = useState("");
  // 新增状态存储反馈消息
  const [feedbackMsg, setFeedbackMsg] = useState("");

  const { user } = useAuth();

  // 异步处理用户名更新
  const handleUpdateUsername = async () => {
    try {
      const msg = await writeUserName(user.uid, username);
      setFeedbackMsg(msg);
      setUserName(""); // 可选:更新成功后清空输入框
    } catch (err) {
      setFeedbackMsg(err);
    }
  };

  return (
    <View style={styles.container}> {/* 修正原代码的属性错误:styles → style */}
      <Text style={styles.title}> Edit Profile </Text>

      <TextInput
        style={styles.input}
        placeholder="Username"
        placeholderTextColor="#aaaaaa"
        onChangeText={(text) => setUserName(text)}
        value={username}
        underlineColorAndroid="transparent"
        autoCapitalize="none"
      />
      <TouchableOpacity
        style={[styles.button, { backgroundColor: "#9D3BEA" }]}
        onPress={handleUpdateUsername}
      >
        <Text style={styles.buttonTitle}>Change username</Text>
      </TouchableOpacity>

      {/* 渲染反馈消息,根据内容区分颜色 */}
      {feedbackMsg !== "" && (
        <Text style={{ marginTop: 16, color: feedbackMsg.includes("成功") ? "green" : "red" }}>
          {feedbackMsg}
        </Text>
      )}
    </View>
  );
};

export default EditProfileScreen;

关键改动说明

  • Promise化异步操作:解决原代码中异步查询无法直接返回结果的问题,让组件可以通过await获取操作状态。
  • 状态管理反馈:通过feedbackMsg状态存储消息,React会自动根据状态更新页面渲染。
  • 错误统一处理:用try/catch捕获所有校验、查询、更新环节的错误,统一展示给用户。
  • 修正小bug:修复原代码中View组件的属性错误(styles改为style)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 05:35:20