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

React Native中点击按钮后如何实现类似useEffect效果的AJAX调用

问题原因解析
  • 关于useEffect的执行规则:useEffect 不传第二个依赖数组参数时,每次组件渲染完成后都会执行,这就是你之前把getJoke直接放进useEffect会无限调用接口的原因。如果你要让useEffect只在挂载时执行一次,要传空数组[]作为依赖。
  • 关于Hook调用规则:React明确要求Hook只能在函数组件的最顶层调用,不能在普通函数、条件判断、循环内部调用,所以你把useEffect放进getJoke里会触发无效Hook调用的报错。
  • 你现在用buttonPress状态中转的逻辑是多余的:React不会「持续检测」状态变化,只有当状态更新触发组件重渲染时,对应的逻辑才会执行,不过这种中转完全没有必要,点击按钮直接触发接口调用即可。
修正后的实现方案

你要的点击按钮触发一次接口、更新文本的效果完全不需要用useEffect,直接把接口调用函数绑定到按钮的onPress事件即可,修正后的代码如下:

import { StatusBar } from 'expo-status-bar';
import React, { useState } from 'react';
import { StyleSheet, Text, View, Button} from 'react-native';

export default function App() {
  // 初始加载状态设为false,因为首次进入不需要自动请求接口
  const [isLoading, setLoading] = useState(false);
  const [data, setData] = useState('暂无笑话,点击按钮获取');
  const [error, setError] = useState(false);

  const getJoke = async () => {
    // 调用接口前先重置状态
    setLoading(true);
    setError(false);
    try {
      const response = await fetch('https://api.chucknorris.io/jokes/random');
      const json = await response.json();
      setData(json.value);
    } catch (error) {
      console.error(error);
      setError(true);
      setData('获取笑话失败,请重试');
    } finally {
      setLoading(false);
    }
  }

  return (
    <View style={{ flex: 1, padding: 24 }}>
      <Text>Press button to get a random joke:</Text>
      {/* 点击按钮直接调用getJoke函数 */}
      <Button 
        title={isLoading ? "获取中..." : "获取笑话"} 
        onPress={getJoke}
        disabled={isLoading}
      />
      {error && <Text style={{color: 'red'}}>请求出错,请稍后再试</Text>}
      <Text>{isLoading ? "加载中..." : data}</Text>
    </View>
  );
}

优化点说明:

  • 去掉了冗余的buttonPress状态和useEffect逻辑,直接绑定点击事件触发接口调用,符合你要的类似网页AJAX点击触发的效果
  • 新增了加载中状态的按钮禁用和文本提示,避免用户重复点击
  • 新增了错误状态的文本提示,交互体验更完善

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 19:15:04