使用setState和Food Data Central API(USDA)来响应本机无限循环

时间:2020-07-07 23:06:35

标签: javascript reactjs react-native react-hooks

所需

我想查询Food Data Central开放API中的数据以显示在应用程序中。

FDC API:https://fdc.nal.usda.gov/api-guide.html

问题

尝试使用setState记录从FDC食物数据库检索到的数据时出现无限循环。

这是我当前拥有的代码。

import React, { useState } from 'react';
import {
  Text,
  View,
} from 'react-native';

export default function App() {

   const [data, setData] = useState([]);

   const getRecipes = async() => {
    const response = await fetch(
      'https://api.nal.usda.gov/fdc/v1/foods/search?api_key=(MY_KEY_HERE)&query=Cheddar%20Cheese&pageSize=1'
    )

    const dataGrabbed = await response.json();
    
    setData(dataGrabbed);
  }

  getRecipes();

  console.log(data);

  return (
    <View style={{ flex: 1, padding: 24, }}>
      <Text> This is just used as a placeholder </Text>
    </View>
  )
}

现在的问题是,这确实将FDC API捕获的数据正确分配给“数据”,但是由于我假设(经过大量研究)每次调用渲染函数时,它都会创建无限循环。调用setData,依次触发该函数。

有没有没有无限循环的使用setData的方法?仅仅是为了我可以显示返回函数中提供的数据?

注意::我还尝试在react native中使用类组件结构,但使用功能组件结构会获得更好的结果。

(我是JavaScript和React Native的新手。)

3 个答案:

答案 0 :(得分:0)

在您的情况下,导致无限循环的问题是由于每次设置状态时都会重新渲染功能组件。仅供参考,每次您从 useState 调用任何函数以更新状态值时,组件都会重新渲染,如果组件重新渲染了您会再次调用所有变量,那么您将无法直接创建此 const getRecipes

为避免任何此类行为,您可以使用React中的另一个挂钩,即 useEffect ,这将仅在需要时(例如仅在组件的初始安装时或当某些值更改时)帮助您进行此调用。您的组件。要了解更多有关此内容的信息,请访问https://reactjs.org/docs/hooks-effect.html

对于您的情况,您可以将组件更改为如下所示:-

import React, { useState, useEffect } from 'react';
import {
  Text,
  View,
} from 'react-native';

export default function App() {

  const [data, setData] = useState([]);

  useEffect(async () => {
    const response = await fetch(
     'https://api.nal.usda.gov/fdc/v1/foods/search?api_key=(MY_KEY_HERE)&query=Cheddar%20Cheese&pageSize=1'
    );
    const dataGrabbed = await response.json();
    setData(dataGrabbed);
  }, [])    

  console.log(data);

  return (
    <View style={{ flex: 1, padding: 24, }}>
      <Text> This is just used as a placeholder </Text>
    </View>
  )
}

useEffect 仅在组件初始安装时进行API调用,而不会进行无限循环。享受吧!

答案 1 :(得分:0)

您必须从React导入useEffect来初始化“屏幕”的状态并阅读更多有关该信息的信息,我写了一个应如何使用的示例:

import React, { useState, useEffect } from 'react';
import {
Text,
View,
} from 'react-native';

export default function App() {

const [data, setData] = useState([]);

useEffect (()=> {
const response = await fetch(
  'https://api.nal.usda.gov/fdc/v1/foods/search?api_key=(MY_KEY_HERE)&query=Cheddar%20Cheese&pageSize=1'
);
const dataGrabbed = await response.json();
setData(dataGrabbed);
}, []);

return (
<View style={{ flex: 1, padding: 24, }}>
  <Text> This is just used as a placeholder </Text>
</View>
)
}

答案 2 :(得分:0)

您需要在useEffect()中调用您的api

useEffect(() => {
   // api call goes here
}, []);