1

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

我下面的代码有效,但对我来说并不“正确”。useEffect() 在页面加载后运行?似乎运行了多次。我将按钮点击计数为真,然后在 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>
);
}
4

2 回答 2

2

删除所有useEffect块并替换为useEffect以下

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

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

于 2021-08-31T03:59:42.470 回答
2

每次渲染后运行

  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]);

Invalid hook call 的原因是规则很少。

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

于 2021-08-31T04:17:55.413 回答