英文:
Fetch data API and export result into another component
问题
以下是您提供的代码的中文翻译:
我在使用React Native时是新手,我试图从一个API中获取JSON数据,然后将其导出到一个Context中,以便在Provider中使用它。当我在一个列表组件中导入获取数据的文件时,一切都正常,但当我在Context中导入它时,却收到一个空数组,可能是因为在完成获取结果之前导出了数据。
我该如何导出数据,以便将其放入Provider中,使得状态对需要此信息的应用程序部分可用?
我已经尝试过使用useEffect,async/await,promise等,使用我在互联网上找到的示例,但我没有成功
获取文件:
import React, { useState, useEffect } from 'react';
export type Products = {
item: {
id: number,
title: string,
description: string,
price: number,
discountPercentage: number,
rating: number,
stock: number,
brand: string,
category: string,
thumbnail: string,
images: []
}
}
export const getAllProducts = () => {
const [data, setData] = useState([]);
const url = "https://dummyjson.com/products"
useEffect(() => {
fetch(url)
.then((resp) => resp.json())
.then((json) => setData(json.products))
.catch((error) => console.error(error))
}, []);
return {
data
}
}
Context文件:
import React, { createContext, useReducer } from 'react'
import { getAllProducts, Products } from '../data/products'
const { data } = getAllProducts() // console.log(data) 结果: data = []
const initialState = { data }
const ProductsContext = createContext({})
type State = {
products: [Products['item']]
};
type Actions = {
type: string,
payload: Products['item'],
}
const actions: any = {
createProduct(state: State, action: Actions) {
const product = action.payload
product.id = Math.random()
return {
...state,
products: [...state.products, product]
}
},
updateProduct(state: State, action: Actions) {
const updated = action.payload
return {
...state,
products: state.products.map(u => u.id === updated.id ? updated : u)
}
},
deleteProduct(state: State, action: Actions) {
const product = action.payload
return {
...state,
products: state.products.filter((prod: { id: number }) => prod.id !== product.id)
}
}
}
export const ProductsProvider = (props: any) => {
function reducer(state: any, action: Actions) {
const fn: any = actions[action.type]
return fn ? fn(state, action) : state
}
const [state, dispatch] = useReducer(reducer, initialState)
return (
<ProductsContext.Provider value={{ state, dispatch }}>
{props.children}
</ProductsContext.Provider>
)
}
export default ProductsContext
列表文件(它正常工作):
import React, { useContext } from 'react'
import { View, FlatList } from 'react-native'
import { getAllProducts, Products } from '../data/products'
import ProductCard from '../components/ProductCard';
import ProductsContext from '../context/ProductContext';
const numColumns = 2
const isAdmin: boolean = true
export default (props: any) => {
const { data } = getAllProducts() // 这里的data是一个包含数据的对象数组
//const { state, dispatch }: any = useContext(ProductsContext)
function getProductItemCard({ item: prod }: Products) {
const nav = props.navigation
return (
<ProductCard
product={{ prod }}
navigation={{ nav }}
isAdmin={isAdmin}
/>
)
}
return (
<View>
<FlatList
numColumns={numColumns}
keyExtractor={p => `${p['id']}`}
data={data}
renderItem={getProductItemCard}
/>
</View>
)
}
英文:
I'm new in react native, and i'm trying to capture json data from an API, and then exporting it to a Context to be able to use it in a Provider, when I import the file that fetchs, in a list component for example, everything happens normally, but when I import it in the Context , an empty array arrives, probably because it was exporting the data before finalizing the fetch result.
How can I export the data so that I can put it in the providers to make the state available to the part of the application that needs this information?
I already tried using useEffect , async / await , promise, with the examples I found on the internet, but I was unsuccessful
Fetch file
import React, { useState, useEffect } from 'react';
export type Products = {
item: {
id: number,
title: string,
description: string,
price: number,
discountPercentage: number,
rating: number,
stock: number,
brand: string,
category: string,
thumbnail: string,
images: []
}
}
export const getAllProducts = () => {
const [data, setData] = useState([]);
const url = "https://dummyjson.com/products"
useEffect(() => {
fetch(url)
.then((resp) => resp.json())
.then((json) => setData(json.products))
.catch((error) => console.error(error))
}, []);
// result of console.log =
// LOG Running "rncrud" with {"rootTag":241}
// LOG []
// LOG []
// LOG [{"brand": "Apple", "category": "smartphones", "description"..........]}
return {
data
}
}
Context file :
import React, { createContext, useReducer } from 'react'
import { getAllProducts, Products } from '../data/products'
const { data } = getAllProducts() // console.log(data) result : data = []
const initialState = { data }
const ProductsContext = createContext({})
type State = {
products: [Products['item']]
};
type Actions = {
type: string,
payload: Products['item'],
}
const actions: any = {
createProduct(state: State, action: Actions) {
const product = action.payload
product.id = Math.random()
return {
...state,
products: [...state.products, product]
}
},
updateProduct(state: State, action: Actions) {
const updated = action.payload
return {
...state,
products: state.products.map(u => u.id === updated.id ? updated : u)
}
},
deleteProduct(state: State, action: Actions) {
const product = action.payload
return {
...state,
products: state.products.filter((prod: { id: number }) => prod.id !== product.id)
}
}
}
export const ProductsProvider = (props: any) => {
function reducer(state: any, action: Actions) {
const fn: any = actions[action.type]
return fn ? fn(state, action) : state
}
const [state, dispatch] = useReducer(reducer, initialState)
return (
<ProductsContext.Provider value={{ state, dispatch }}>
{props.children}
</ProductsContext.Provider>
)
}
export default ProductsContext
List file where it works
import React, { useContext } from 'react'
import { View, FlatList } from 'react-native'
import { getAllProducts, Products } from '../data/products'
import ProductCard from '../components/ProductCard';
import ProductsContext from '../context/ProductContext';
const numColumns = 2
const isAdmin: boolean = true
export default (props: any) => {
const { data } = getAllProducts() // here data is an array of objects with data
//const { state, dispatch }: any = useContext(ProductsContext)
function getProductItemCard({ item: prod }: Products) {
const nav = props.navigation
return (
<ProductCard
product={{ prod }}
navigation={{ nav }}
isAdmin={isAdmin}
/>
)
}
return (
<View>
<FlatList
numColumns={numColumns}
keyExtractor={p => `${p['id']}`}
data={data}
renderItem={getProductItemCard}
/>
</View>
)
}
答案1
得分: 1
获取数据 API 并将结果导出到另一个组件
自定义 Hooks
我们可以在组件之外使用 useEffect 创建自定义 Hook,非常简单。
import { useEffect, useState } from "react";
const url = "https://dummyjson.com/products";
export const useProducts = () => {
const [loading, setLoading] = useState(false);
const [products, setProducts] = useState([]);
useEffect(() => {
fetchProducts();
}, []);
const fetchProducts = async () => {
try {
setLoading(true);
const res = await fetch(url).then((data) => data.json());
setProducts(res.products);
setLoading(false);
} catch (error) {
setLoading(false);
throw new Error(error);
} finally {
setLoading(false);
}
};
return [products, loading];
};
然后我们可以这样使用:
const [products, loading] = useProducts();
可重复使用的 Hook 函数
- 请注意,我只展示了 React Web 中的示例,但在 React Native 中也有相同的 Hook 和逻辑。
- 希望这对你有所帮助。
英文:
Fetch data API and export result into another component
custom Hooks
we can create a custom hook outside of component using useeffect. it is very simple
import { useEffect, useState } from "react";
const url = "https://dummyjson.com/products";
export const useProducts = () => {
const [loading, setLoading] = useState(false);
const [products, setProducts] = useState([]);
useEffect(() => {
fetchProducts();
}, []);
const fetchProducts = async () => {
try {
setLoading(true);
const res = await fetch(url).then((data) => data.json());
setProducts(res.products);
setLoading(false);
} catch (error) {
setLoading(false);
throw new Error(error);
} finally {
setLoading(false);
}
};
return [products, loading];
};
and we can use like
const [products, loading] = useProducts();
reusable hook fun
- pls note I just show in react web. but there is same hook and login in react native.
- I hope that can help you
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论