React Native点击骰子组件时调用接口更新Text文本的方法
问题根源
你打印得到Promise对象确实是文本无法更新的诱因之一,但代码存在多处逻辑错误才是核心原因:
async声明的函数默认返回Promise对象,你既没有接收Promise resolve后的实际返回值,也没有把接口返回的文本存入组件状态,React无法感知数据变化,自然不会触发视图更新- 你定义的
button是独立的普通函数,其内部声明的getUrl属于局部作用域函数,外部根本无法访问button.getUrl,render中写的这个引用完全是无效值 - 跨组件事件逻辑错误:Dice组件的点击事件直接绑定了外部独立函数,这个函数没有权限修改Boxes组件的内部状态,就算请求成功也没法更新文本
- 现有
button函数内虽然调用了getUrl(),但没有接收返回值,接口返回的建议文本没有被任何变量存储,等于无效请求
修复方案
核心思路:把需要动态更新的建议文本存在Boxes组件的state中,接口请求逻辑放在Boxes组件内部,再把触发请求的回调通过props传递给Dice子组件,点击骰子时调用回调更新父组件状态即可,React检测到state变化会自动重新渲染,更新文本内容。
修复后的完整代码:
Boxes.js
import React from 'react'; import { View, Text } from 'react-native'; // 注意替换成你项目里对应的引入路径 import PatternDivider from './PatternDivider'; import Dice from './Dice'; import styles from './styles'; // 你的样式文件路径 export default class Boxes extends React.Component { // 初始化状态,存储要显示的建议文本,填入默认文案 state = { adviceText: "It is easy to sit up and take notice, what's difficult is getting up and taking action" } // 类组件中用箭头函数定义方法,避免this指向错误 fetchNewAdvice = async () => { // 加错误捕获,避免请求失败导致应用崩溃 try { const url = "https://api.adviceslip.com/advice"; const response = await fetch(url); const data = await response.json(); // 调用setState更新状态,触发视图重渲染 this.setState({ adviceText: data.slip.advice }) } catch (error) { console.log('获取建议失败:', error); } } render() { return ( <View style={styles.box}> <Text style={styles.header}>Advice</Text> {/* 直接从state中读取要显示的文本 */} <Text style={styles.advice}> {this.state.adviceText} </Text> <PatternDivider /> {/* 把请求回调通过props传给Dice组件 */} <Dice onDicePress={this.fetchNewAdvice} /> </View> ); } }
Dice.js
import React from 'react'; import { Pressable, Image } from 'react-native'; import styles from './styles'; // 你的样式文件路径 export default class Dice extends React.Component { render() { return ( // 点击时调用父组件传入的回调 <Pressable style={styles.circle} onPress={this.props.onDicePress}> <Image source={require("../assets/icon-dice.png")} style={styles.dice} /> </Pressable> ); } }
优化建议
- 删除原文件中独立的
button函数,所有和组件状态相关的逻辑都应该收敛在组件内部,避免作用域访问错误 - 所有带
async/await的网络请求必须加try/catch错误捕获,防止网络异常、接口返回格式不符时抛出未捕获异常导致应用闪退 - 可以增加加载状态:请求过程中给骰子按钮加禁用态、降低透明度,避免用户快速重复点击触发多次无效请求
- 修复原默认文案的拼写错误:原代码中
getting uu应为getting up - 若项目使用的React版本支持Hooks,可将类组件改写为函数组件,代码更简洁易维护,函数组件版本的Boxes参考如下:
import React, { useState, useCallback } from 'react'; import { View, Text } from 'react-native'; import PatternDivider from './PatternDivider'; import Dice from './Dice'; import styles from './styles'; export default function Boxes() { const [adviceText, setAdviceText] = useState( "It is easy to sit up and take notice, what's difficult is getting up and taking action" ); const fetchNewAdvice = useCallback(async () => { try { const response = await fetch("https://api.adviceslip.com/advice"); const data = await response.json(); setAdviceText(data.slip.advice); } catch (error) { console.log('获取建议失败:', error); } }, []); return ( <View style={styles.box}> <Text style={styles.header}>Advice</Text> <Text style={styles.advice}>{adviceText}</Text> <PatternDivider /> <Dice onDicePress={fetchNewAdvice} /> </View> ) }
内容的提问来源于stack exchange,提问作者Agam Singh
相关产品推荐
相关产品推荐

