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
相关产品推荐
相关产品推荐

