如何在React Native的卡片中从API调用加载数据?

huangapple go评论107阅读模式
英文:

How to load data from api call in card with react native?

问题

如何返回“roofvogels”和“parkieten”两个项目?

要返回“roofvogels”和“parkieten”这两个项目,你需要遍历item.subcategories数组,并为每个子类别创建一个单独的组件。以下是如何在SubCategoryScreen组件中实现它的示例代码:

  1. export const SubCategoryScreen = () => {
  2. const { subCategoryList } = useContext(CategoryContext);
  3. return (
  4. <SafeArea>
  5. <CategoryList
  6. data={subCategoryList}
  7. renderItem={({ item }) => (
  8. <Spacer position="bottom" size="large">
  9. {item.subcategories.map((subcategory) => (
  10. <SubCategoryInfoCard key={subcategory.id} subcategory={subcategory} />
  11. ))}
  12. </Spacer>
  13. )}
  14. keyExtractor={(item) => item.name}
  15. />
  16. </SafeArea>
  17. );
  18. };

在这个示例中,我们使用了map函数来遍历item.subcategories数组中的每个子类别对象,并为每个子类别创建了一个SubCategoryInfoCard组件。这将允许你在屏幕上呈现所有子类别,包括“roofvogels”和“parkieten”。

英文:

I have a react native app and I try to navigate to a card component where the data from a backend call has to be loaded. But untill now the data call has not been triggered from the backend.

So I have a service:

  1. export const fetchSubCategoryData = async () =&gt; {
  2. try {
  3. const response = await fetch(&quot;http://192.168.1.68:8000/api/categories/2&quot;, {
  4. method: &quot;GET&quot;,
  5. headers: {
  6. Accept: &quot;application/json&quot;,
  7. &quot;Content-Type&quot;: &quot;application/json&quot;,
  8. },
  9. });
  10. if (!response.ok) {
  11. throw new Error(&quot;Network response was not ok&quot;);
  12. }
  13. return await response.json();
  14. } catch (error) {
  15. console.error(&quot;There was a problem with the fetch operation:&quot;, error);
  16. throw error;
  17. }
  18. };

and a context:

  1. export const CategoryContext = createContext();
  2. export const CategoryContextProvider = ({ children }) =&gt; {
  3. const [categoryList, setCategoryList] = useState([]);
  4. const [subCategoryList, setSubCategoryList] = useState([]);
  5. const [loading, setLoading] = useState(false);
  6. const [error, setError] = useState(null);
  7. const [] = useState([]);
  8. const retrieveCategories = () =&gt; {
  9. setLoading(true);
  10. setTimeout(() =&gt; {
  11. fetchCategoryData()
  12. .then((results) =&gt; {
  13. setLoading(false);
  14. setCategoryList(results);
  15. })
  16. .catch((err) =&gt; {
  17. setLoading(false);
  18. setError(err);
  19. });
  20. });
  21. };
  22. const retrieveSubCategories = () =&gt; {
  23. setLoading(true);
  24. setTimeout(() =&gt; {
  25. fetchSubCategoryData()
  26. .then((results) =&gt; {
  27. setLoading(false);
  28. setSubCategoryList(results);
  29. })
  30. .catch((err) =&gt; {
  31. setLoading(false);
  32. setError(err);
  33. });
  34. });
  35. };
  36. useEffect(() =&gt; {
  37. retrieveCategories();
  38. }, []);
  39. useEffect(() =&gt; {
  40. retrieveSubCategories();
  41. }, []);
  42. return (
  43. &lt;CategoryContext.Provider
  44. value={{
  45. categoryList,
  46. subCategoryList,
  47. loading,
  48. error,
  49. }}&gt;
  50. {children}
  51. &lt;/CategoryContext.Provider&gt;
  52. );
  53. };

And the component from where I want to navigate to the other component:

  1. export const CategoryScreen = ({ navigation }) =&gt; {
  2. const { loading, error, categoryList } = useContext(CategoryContext);
  3. return (
  4. &lt;SafeArea&gt;
  5. {loading &amp;&amp; (
  6. &lt;LoadingContainer&gt;
  7. &lt;ActivityIndicator animating={true} color={MD2Colors.green200} /&gt;
  8. &lt;/LoadingContainer&gt;
  9. )}
  10. &lt;Search /&gt;
  11. &lt;CategoryList
  12. data={categoryList}
  13. renderItem={({ item }) =&gt; {
  14. return (
  15. &lt;TouchableOpacity onPress={() =&gt; navigation.navigate(&quot;groepen&quot;, { category: item })}&gt;
  16. &lt;Spacer position=&quot;bottom&quot; size=&quot;large&quot;&gt;
  17. &lt;CategoryInfoCard category={item} /&gt;
  18. &lt;/Spacer&gt;
  19. &lt;/TouchableOpacity&gt;
  20. );
  21. }}
  22. keyExtractor={(item) =&gt; item.name}
  23. /&gt;
  24. &lt;/SafeArea&gt;
  25. );
  26. };

And then the component where the data hast to been show on the card:

  1. export const SubCategoryScreen = () =&gt; {
  2. const { subCategoryList } = useContext(CategoryContext);
  3. return (
  4. &lt;SafeArea&gt;
  5. {console.log(&quot;test&quot;)}
  6. &lt;CategoryList
  7. data={subCategoryList}
  8. renderItem={({ item }) =&gt; {
  9. console.log(item);
  10. return (
  11. &lt;Spacer position=&quot;bottom&quot; size=&quot;large&quot;&gt;
  12. &lt;CategoryInfoCard category={item} /&gt;
  13. &lt;/Spacer&gt;
  14. );
  15. }}
  16. keyExtractor={(item) =&gt; item.name}
  17. /&gt;
  18. &lt;/SafeArea&gt;
  19. );
  20. };

And this is the output from the api call:

  1. GET /api/categories/2/
  2. HTTP 200 OK
  3. Allow: GET, PUT, PATCH, DELETE, HEAD, OPTIONS
  4. Content-Type: application/json
  5. Vary: Accept
  6. {
  7. &quot;id&quot;: 2,
  8. &quot;name&quot;: &quot;vogels&quot;,
  9. &quot;description&quot;: &quot;vogels&quot;,
  10. &quot;legislation&quot;: &quot;&quot;,
  11. &quot;review&quot;: &quot;&quot;,
  12. &quot;eaza&quot;: &quot;&quot;,
  13. &quot;images&quot;: &quot;http://192.168.1.68:8000/media/photos/categories/birds.png&quot;,
  14. &quot;animals&quot;: [],
  15. &quot;subcategories&quot;: [
  16. {
  17. &quot;id&quot;: 3,
  18. &quot;name&quot;: &quot;roofvogels&quot;,
  19. &quot;description&quot;: &quot;roofvogels&quot;,
  20. &quot;images&quot;: null
  21. },
  22. {
  23. &quot;id&quot;: 5,
  24. &quot;name&quot;: &quot;parkieten&quot;,
  25. &quot;description&quot;: &quot;parkieten&quot;,
  26. &quot;images&quot;: &quot;http://192.168.1.68:8000/media/photos/categories/predator_gqLXVoK.jpg&quot;
  27. }
  28. ],
  29. &quot;category&quot;: null
  30. }

ah, oke. I just figured something out.

So if I do this:

  1. const retrieveSubCategories = () =&gt; {
  2. setLoading(true);
  3. setTimeout(() =&gt; {
  4. fetchSubCategoryData()
  5. //.then(subCategoryTransform)
  6. .then((results) =&gt; {
  7. setLoading(false);
  8. setSubCategoryList([results]);
  9. })
  10. .catch((err) =&gt; {
  11. setLoading(false);
  12. setError(err);
  13. });
  14. });
  15. };

with this:

  1. export const SubCategoryScreen = () =&gt; {
  2. const { subCategoryList } = useContext(CategoryContext);
  3. return (
  4. &lt;SafeArea&gt;
  5. &lt;CategoryList
  6. data={subCategoryList}
  7. renderItem={({ item }) =&gt; {
  8. console.log(&quot;SUBCATEGORES&quot;, item.subcategories);
  9. return (
  10. &lt;Spacer position=&quot;bottom&quot; size=&quot;large&quot;&gt;
  11. &lt;SubCategoryInfoCard subcategories={item.subcategories[0]} /&gt;
  12. &lt;/Spacer&gt;
  13. );
  14. }}
  15. keyExtractor={(item) =&gt; item.name}
  16. /&gt;
  17. &lt;/SafeArea&gt;
  18. );
  19. };

Then I see the name and image of one card item: roofvogels.

But if I do this:

  1. &lt;SubCategoryInfoCard subcategories={item.subcategories} /&gt;

This doesn't work.

And the api call in the console.log is:

  1. SUBCATEGORES Array [
  2. Object {
  3. Object {
  4. &quot;description&quot;: &quot;roofvogels&quot;,
  5. &quot;id&quot;: 3,
  6. &quot;images&quot;: &quot;http://192.168.1.68:8000/media/photos/categories/predator_ETI4KPC.jpg&quot;,
  7. &quot;name&quot;: &quot;roofvogels&quot;,
  8. },
  9. Object {
  10. &quot;description&quot;: &quot;parkieten&quot;,
  11. &quot;id&quot;: 5,
  12. &quot;images&quot;: &quot;http://192.168.1.68:8000/media/photos/categories/predator_gqLXVoK.jpg&quot;,
  13. &quot;name&quot;: &quot;parkieten&quot;,
  14. },
  15. ]

So I try it like:

  1. export const SubCategoryScreen = () =&gt; {
  2. const { subCategoryList } = useContext(CategoryContext);
  3. return (
  4. &lt;SafeArea&gt;
  5. &lt;CategoryList
  6. data={subCategoryList}
  7. renderItem={({ item }) =&gt; {
  8. console.log(&quot;SUBCATEGORES&quot;, item.subcategories);
  9. return (
  10. &lt;Spacer position=&quot;bottom&quot; size=&quot;large&quot;&gt;
  11. &lt;Text&gt;{item.subcategories} &lt;/Text&gt;
  12. &lt;/Spacer&gt;
  13. );
  14. }}
  15. keyExtractor={(item) =&gt; item.name}
  16. /&gt;
  17. &lt;/SafeArea&gt;
  18. );
  19. };

But then I get this error:

  1. Error: Objects are not valid as a React child (found: object with keys {id, name, description, images}). If you meant to render a collection of children, use an array instead.

Question:How to return both of items: roofvogels and parkieten?

答案1

得分: 1

你没有实际调用发出 API 请求的函数。

  1. useEffect(() => {}, [retrieveSubCategories]);

尝试:

  1. useEffect(() => {
  2. retrieveSubCategories();
  3. }, []);
英文:

You're not actually calling the function which makes the api request.

  1. useEffect(() =&gt; {}, [retrieveSubCategories]);

Try:

  1. useEffect(() =&gt; {
  2. retrieveSubCategories();
  3. }, []);

huangapple
  • 本文由 发表于 2023年2月27日 00:11:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/75573284.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定