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

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

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

问题

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

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

export const SubCategoryScreen = () => {
  const { subCategoryList } = useContext(CategoryContext);

  return (
    <SafeArea>
      <CategoryList
        data={subCategoryList}
        renderItem={({ item }) => (
          <Spacer position="bottom" size="large">
            {item.subcategories.map((subcategory) => (
              <SubCategoryInfoCard key={subcategory.id} subcategory={subcategory} />
            ))}
          </Spacer>
        )}
        keyExtractor={(item) => item.name}
      />
    </SafeArea>
  );
};

在这个示例中,我们使用了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:


export const fetchSubCategoryData = async () =&gt; {
	try {
		const response = await fetch(&quot;http://192.168.1.68:8000/api/categories/2&quot;, {
			method: &quot;GET&quot;,
			headers: {
				Accept: &quot;application/json&quot;,
				&quot;Content-Type&quot;: &quot;application/json&quot;,
			},
		});
		if (!response.ok) {
			throw new Error(&quot;Network response was not ok&quot;);
		}

		return await response.json();
	} catch (error) {
		console.error(&quot;There was a problem with the fetch operation:&quot;, error);
		throw error;
	}
};
 

and a context:

export const CategoryContext = createContext();

export const CategoryContextProvider = ({ children }) =&gt; {
	const [categoryList, setCategoryList] = useState([]);
	const [subCategoryList, setSubCategoryList] = useState([]);
	const [loading, setLoading] = useState(false);
	const [error, setError] = useState(null);
	const [] = useState([]);

	const retrieveCategories = () =&gt; {
		setLoading(true);
		setTimeout(() =&gt; {
			fetchCategoryData()
				.then((results) =&gt; {
					setLoading(false);
					setCategoryList(results);
				})
				.catch((err) =&gt; {
					setLoading(false);
					setError(err);
				});
		});
	};

	const retrieveSubCategories = () =&gt; {
		setLoading(true);
		setTimeout(() =&gt; {
			fetchSubCategoryData()				
				.then((results) =&gt; {
					setLoading(false);
					setSubCategoryList(results);
				})
				.catch((err) =&gt; {
					setLoading(false);
					setError(err);
				});
		});
	};

	useEffect(() =&gt; {
		retrieveCategories();
	}, []);

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

	return (
		&lt;CategoryContext.Provider
			value={{
				categoryList,
				subCategoryList,
				loading,
				error,
			}}&gt;
			{children}
		&lt;/CategoryContext.Provider&gt;
	);
};

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

export const CategoryScreen = ({ navigation }) =&gt; {
	const { loading, error, categoryList } = useContext(CategoryContext);
	return (
		&lt;SafeArea&gt;
			{loading &amp;&amp; (
				&lt;LoadingContainer&gt;
					&lt;ActivityIndicator animating={true} color={MD2Colors.green200} /&gt;
				&lt;/LoadingContainer&gt;
			)}
			&lt;Search /&gt;
			&lt;CategoryList
				data={categoryList}
				renderItem={({ item }) =&gt; {
					return (
						&lt;TouchableOpacity onPress={() =&gt; navigation.navigate(&quot;groepen&quot;, { category: item })}&gt;
							&lt;Spacer position=&quot;bottom&quot; size=&quot;large&quot;&gt;
								&lt;CategoryInfoCard category={item} /&gt;
							&lt;/Spacer&gt;
						&lt;/TouchableOpacity&gt;
					);
				}}
				keyExtractor={(item) =&gt; item.name}
			/&gt;
		&lt;/SafeArea&gt;
	);
};

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

export const SubCategoryScreen = () =&gt; {
	const { subCategoryList } = useContext(CategoryContext);

	return (
		&lt;SafeArea&gt;
			{console.log(&quot;test&quot;)}
			&lt;CategoryList
				data={subCategoryList}
				renderItem={({ item }) =&gt; {
					console.log(item);
					return (
						&lt;Spacer position=&quot;bottom&quot; size=&quot;large&quot;&gt;
							&lt;CategoryInfoCard category={item} /&gt;
						&lt;/Spacer&gt;
					);
				}}
				keyExtractor={(item) =&gt; item.name}
			/&gt;
		&lt;/SafeArea&gt;
	);
};

And this is the output from the api call:



GET /api/categories/2/

HTTP 200 OK
Allow: GET, PUT, PATCH, DELETE, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    &quot;id&quot;: 2,
    &quot;name&quot;: &quot;vogels&quot;,
    &quot;description&quot;: &quot;vogels&quot;,
    &quot;legislation&quot;: &quot;&quot;,
    &quot;review&quot;: &quot;&quot;,
    &quot;eaza&quot;: &quot;&quot;,
    &quot;images&quot;: &quot;http://192.168.1.68:8000/media/photos/categories/birds.png&quot;,
    &quot;animals&quot;: [],
    &quot;subcategories&quot;: [
        {
            &quot;id&quot;: 3,
            &quot;name&quot;: &quot;roofvogels&quot;,
            &quot;description&quot;: &quot;roofvogels&quot;,
            &quot;images&quot;: null
        },
        {
            &quot;id&quot;: 5,
            &quot;name&quot;: &quot;parkieten&quot;,
            &quot;description&quot;: &quot;parkieten&quot;,
            &quot;images&quot;: &quot;http://192.168.1.68:8000/media/photos/categories/predator_gqLXVoK.jpg&quot;
        }
    ],
    &quot;category&quot;: null
}


ah, oke. I just figured something out.

So if I do this:

const retrieveSubCategories = () =&gt; {
		setLoading(true);
		setTimeout(() =&gt; {
			fetchSubCategoryData()
				//.then(subCategoryTransform)
				.then((results) =&gt; {
					setLoading(false);
					setSubCategoryList([results]);
				})
				.catch((err) =&gt; {
					setLoading(false);
					setError(err);
				});
		});
	};

with this:

export const SubCategoryScreen = () =&gt; {
	const { subCategoryList } = useContext(CategoryContext);

	return (
		&lt;SafeArea&gt;
			&lt;CategoryList
				data={subCategoryList}
				renderItem={({ item }) =&gt; {
					console.log(&quot;SUBCATEGORES&quot;, item.subcategories);
					return (
						&lt;Spacer position=&quot;bottom&quot; size=&quot;large&quot;&gt;
							&lt;SubCategoryInfoCard subcategories={item.subcategories[0]} /&gt;
						&lt;/Spacer&gt;
					);
				}}
				keyExtractor={(item) =&gt; item.name}
			/&gt;
		&lt;/SafeArea&gt;
	);
};

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

But if I do this:

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

This doesn't work.

And the api call in the console.log is:

SUBCATEGORES Array [
  Object {
  Object {
    &quot;description&quot;: &quot;roofvogels&quot;,
    &quot;id&quot;: 3,
    &quot;images&quot;: &quot;http://192.168.1.68:8000/media/photos/categories/predator_ETI4KPC.jpg&quot;,
    &quot;name&quot;: &quot;roofvogels&quot;,
  },
  Object {
    &quot;description&quot;: &quot;parkieten&quot;,
    &quot;id&quot;: 5,
    &quot;images&quot;: &quot;http://192.168.1.68:8000/media/photos/categories/predator_gqLXVoK.jpg&quot;,
    &quot;name&quot;: &quot;parkieten&quot;,
  },
]

So I try it like:


export const SubCategoryScreen = () =&gt; {
	const { subCategoryList } = useContext(CategoryContext);

	return (
		&lt;SafeArea&gt;
			&lt;CategoryList
				data={subCategoryList}
				renderItem={({ item }) =&gt; {
					console.log(&quot;SUBCATEGORES&quot;, item.subcategories);
					return (
						&lt;Spacer position=&quot;bottom&quot; size=&quot;large&quot;&gt;
							&lt;Text&gt;{item.subcategories} &lt;/Text&gt;
						&lt;/Spacer&gt;
					);
				}}
				keyExtractor={(item) =&gt; item.name}
			/&gt;
		&lt;/SafeArea&gt;
	);
};

But then I get this error:

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 请求的函数。

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

尝试:

useEffect(() => {
  retrieveSubCategories();
}, []);
英文:

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

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

Try:

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

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:

确定