如何在 React Native 中按下按钮后调用 useEffect() 样式 ajax?

How to do a useEffect() style ajax call after button press in React Native?

我是 React 和 React Native 的新手。 尝试构建一个简单的应用程序,在按下按钮时执行 API 调用。

我下面的代码可以工作,但对我来说“看起来不对”。 页面加载后 useEffect() 是 运行?似乎是 运行 多次。 我将按钮点击计数为 true,然后在 useEffect 中有一个 if 语句。这是否意味着该应用会不断检查按钮是否被按下?

我尝试将 useEffect() 放入 getJoke() 函数中,但 React Native 不喜欢它。 “无效的钩子调用。只能在函数组件的主体内部调用钩子。”

如果我将 getJoke() 放在 useEffect() 中,它会不断调用 api。我在响应后喷射 api 响应。

我只希望按下一个按钮会产生一个 API 调用,如果这是一个网页,按钮下方的文本会像 AJAX 那样更新。

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

export default function App() {

 const [isLoading, setLoading] = useState(true);
 const [data, setData] = useState();
 const [ error, setError ] = useState(false);
 const [buttonPress, setButtonPress] = useState(false);

 const getJoke = async () => {
  try {
   const response = await fetch('https://api.chucknorris.io/jokes/random');
   const json = await response.json();
   console.log(json);
   console.log('Joke: ' + json.value);
   setData(json.value);   // Chuck API provides joke in "value" field. Only saving the joke.

  // Unfortunately you can't call hooks useEffect from here?

 } catch (error) {
   console.error(error);
   setError(true);       
 } finally {
   setLoading(false);
 }
}

// Constant api calls if I do this
 /*
 useEffect(() => {
  getJoke();
 });
 */

 useEffect(() => {
   // Check if button has been pressed, if so update the page
   if(buttonPress){
    getJoke();
    setButtonPress(false);
   }
 });

return (
  <View style={{ flex: 1, padding: 24 }}>
   <Text>Press button to get a random joke:</Text>
   <Button title="Joke" onPress={setButtonPress}/>
  
   <Text>{data}</Text>
  
  </View>
);
}

删除所有 useEffect 块并替换为下面的 useEffect

useEffect(() => {
   // Check if button has been pressed, if so update the page
   if(buttonPress){
    getJoke();
    setButtonPress(false);
   }
}, [buttonPress]);

基本上 useEffect 的工作原理是,通过引入第二个参数,我们说 运行 useEffect 仅当 buttonPress 的值发生变化时。

在每次渲染后运行

  useEffect(() => {
    // Runs after EVERY rendering
  });

在初始渲染后运行一次。

  useEffect(() => {
    // Runs ONCE after initial rendering
  }, []);

仅在任何依赖项值更改时运行。

  useEffect(() => {
    // Runs ONCE after initial rendering
    // and after every rendering ONLY IF `prop` or `state` changes
  }, [prop, state]);

所以,我认为你应该这样做

useEffect(() => {
   // Check if button has been pressed, if so update the page
   if(buttonPress){
    getJoke();
    setButtonPress(false);
   }
}, [buttonPress]);

无效挂钩调用的原因是很少rules

不要在循环、条件或嵌套函数中调用 Hooks