React Native 获取数据API并将结果导出到其他组件

e0bqpujr  于 2023-05-29  发布在  React
关注(0)|答案(1)|浏览(189)

我是react native的新手,我试图从API中捕获json数据,然后将其导出到Context以便能够在Provider中使用它,当我导入提取的文件时,例如在列表组件中,一切正常,但当我将其导入Context时,到达一个空数组,可能是因为它在最终确定提取结果之前导出数据。
如何导出数据,以便将其放入提供程序中,从而使需要此信息的应用程序部分可以使用状态?
我已经试过使用useEffect、async / await、promise,并在网上找到了一些例子,但是没有成功
取文件

  1. import React, { useState, useEffect } from 'react';
  2. export type Products = {
  3. item: {
  4. id: number,
  5. title: string,
  6. description: string,
  7. price: number,
  8. discountPercentage: number,
  9. rating: number,
  10. stock: number,
  11. brand: string,
  12. category: string,
  13. thumbnail: string,
  14. images: []
  15. }
  16. }
  17. export const getAllProducts = () => {
  18. const [data, setData] = useState([]);
  19. const url = "https://dummyjson.com/products"
  20. useEffect(() => {
  21. fetch(url)
  22. .then((resp) => resp.json())
  23. .then((json) => setData(json.products))
  24. .catch((error) => console.error(error))
  25. }, []);
  26. // result of console.log =
  27. // LOG Running "rncrud" with {"rootTag":241}
  28. // LOG []
  29. // LOG []
  30. // LOG [{"brand": "Apple", "category": "smartphones", "description"..........]}
  31. return {
  32. data
  33. }
  34. }

上下文文件:

  1. import React, { createContext, useReducer } from 'react'
  2. import { getAllProducts, Products } from '../data/products'
  3. const { data } = getAllProducts() // console.log(data) result : data = []
  4. const initialState = { data }
  5. const ProductsContext = createContext({})
  6. type State = {
  7. products: [Products['item']]
  8. };
  9. type Actions = {
  10. type: string,
  11. payload: Products['item'],
  12. }
  13. const actions: any = {
  14. createProduct(state: State, action: Actions) {
  15. const product = action.payload
  16. product.id = Math.random()
  17. return {
  18. ...state,
  19. products: [...state.products, product]
  20. }
  21. },
  22. updateProduct(state: State, action: Actions) {
  23. const updated = action.payload
  24. return {
  25. ...state,
  26. products: state.products.map(u => u.id === updated.id ? updated : u)
  27. }
  28. },
  29. deleteProduct(state: State, action: Actions) {
  30. const product = action.payload
  31. return {
  32. ...state,
  33. products: state.products.filter((prod: { id: number }) => prod.id !== product.id)
  34. }
  35. }
  36. }
  37. export const ProductsProvider = (props: any) => {
  38. function reducer(state: any, action: Actions) {
  39. const fn: any = actions[action.type]
  40. return fn ? fn(state, action) : state
  41. }
  42. const [state, dispatch] = useReducer(reducer, initialState)
  43. return (
  44. <ProductsContext.Provider value={{ state, dispatch }}>
  45. {props.children}
  46. </ProductsContext.Provider>
  47. )
  48. }
  49. export default ProductsContext

列出文件的工作位置

  1. import React, { useContext } from 'react'
  2. import { View, FlatList } from 'react-native'
  3. import { getAllProducts, Products } from '../data/products'
  4. import ProductCard from '../components/ProductCard';
  5. import ProductsContext from '../context/ProductContext';
  6. const numColumns = 2
  7. const isAdmin: boolean = true
  8. export default (props: any) => {
  9. const { data } = getAllProducts() // here data is an array of objects with data
  10. //const { state, dispatch }: any = useContext(ProductsContext)
  11. function getProductItemCard({ item: prod }: Products) {
  12. const nav = props.navigation
  13. return (
  14. <ProductCard
  15. product={{ prod }}
  16. navigation={{ nav }}
  17. isAdmin={isAdmin}
  18. />
  19. )
  20. }
  21. return (
  22. <View>
  23. <FlatList
  24. numColumns={numColumns}
  25. keyExtractor={p => `${p['id']}`}
  26. data={data}
  27. renderItem={getProductItemCard}
  28. />
  29. </View>
  30. )
  31. }
qxgroojn

qxgroojn1#

获取数据API,并将结果导出到其他组件
自定义钩子

我们可以使用useeffect在组件外部创建一个自定义钩子。很简单
example

  1. import { useEffect, useState } from "react";
  2. const url = "https://dummyjson.com/products";
  3. export const useProducts = () => {
  4. const [loading, setLoading] = useState(false);
  5. const [products, setProducts] = useState([]);
  6. useEffect(() => {
  7. fetchProducts();
  8. }, []);
  9. const fetchProducts = async () => {
  10. try {
  11. setLoading(true);
  12. const res = await fetch(url).then((data) => data.json());
  13. setProducts(res.products);
  14. setLoading(false);
  15. } catch (error) {
  16. setLoading(false);
  17. throw new Error(error);
  18. } finally {
  19. setLoading(false);
  20. }
  21. };
  22. return [products, loading];
  23. };

我们可以用

  1. const [products, loading] = useProducts();

可重复使用的钩子

  • 请注意,我只是显示在React网络。但是在react native中有相同的hook和login。
  • 希望能帮到你
展开查看全部

相关问题