javascript - 获取数据时使用 useEffect 和 useContext

标签 javascript reactjs next.js

我正在尝试学习如何使用 React 的 Context API 以及 Hooks,并尝试在一个使用 fetch() 的项目上工作。

同时使用两者时,我收到请求,但无法获取我设置的数据,除了加载

import React,{useState, createContext} from 'react';

export const ProductsContext = createContext();

export const ProductsProvider = props => {
    const [categories, setCategories] = useState({ categories: {} });
    const [products, setProducts] = useState({ products: {} });
    const [loading, setLoading] = useState(true);
    useEffect(() => {
        (async () => {
            const [categoriesResult, productsResult] = await Promise.all([fetch('http://localhost:3000/api/categories'), fetch('http://localhost:3000/api/products')]);
            setCategories(categoriesResult);
            setProducts(productsResult);
            setLoading(false);
          })();
        }, []);
    return (
    <ProductsContext.Provider value={ { products, categories, loading } }>
        {props.children}
    </ProductsContext.Provider>
    );
}

在这里,我正在创建一个上下文,我希望通过提供者传递产品(和类别)。

import React, { useContext } from 'react';
import { ProductsContext } from './ProductsContext';


const Products = () => {
    const {products, categories, loading} = useContext(ProductsContext);
    return (
        <div className="products">
            { console.log(products, categories, loading) }
        </div>
    ); 
};

页面

import React from 'react';
import Header from './Header';
import Banner from './Banner';
import ProductsContainer from './Products/ProductsContainer';
import {ProductsProvider} from './Products/ProductsContext';
const Page = () => (

    <>
      <Header/>
      <Banner/>
      <ProductsProvider>
        <ProductsContainer/>
      </ProductsProvider>
    </>

);

export default Page;

这是我通过 console.log 得到的结果:

{products: {…}} Response {type: "basic", url: "http://localhost:3000/api/categories", redirected: false, status: 200, ok: true, …} true
Products.js:9 Response {type: "basic", url: "http://localhost:3000/api/products", redirected: false, status: 200, ok: true, …} Response {type: "basic", url: "http://localhost:3000/api/categories", redirected: false, status: 200, ok: true, …} true
Products.js:9 Response {type: "basic", url: "http://localhost:3000/api/products", redirected: false, status: 200, ok: true, …} Response {type: "basic", url: "http://localhost:3000/api/categories", redirected: false, status: 200, ok: true, …} false
Products.js:9 Response {type: "basic", url: "http://localhost:3000/api/products", redirected: false, status: 200, ok: true, …} Response {type: "basic", url: "http://localhost:3000/api/categories", redirected: false, status: 200, ok: true, …} false
Products.js:9 Response {type: "basic", url: "http://localhost:3000/api/products", redirected: false, status: 200, ok: true, …} Response {type: "basic", url: "http://localhost:3000/api/categories", redirected: false, status: 200, ok: true, …} false
Products.js:9 Response {type: "basic", url: "http://localhost:3000/api/products", redirected: false, status: 200, ok: true, …} Response {type: "basic", url: "http://localhost:3000/api/categories", redirected: false, status: 200, ok: true, …} false

如您所见,没有数据,但加载发生了变化。

我做错了什么?如何通过 Context API 传递产品?

最佳答案

随意阅读,React.useContext() 看起来很有用。我看到的问题是 React 状态变量 categoriesproduct 被设置为来自 fetch() 的响应并根据 MDN's fetch() reference , fetch 返回一个从 Promise 解析为 Response 的值,这并不完全是您想要的。

但这已经很接近了!你应该做类似的事情

  setCategories(categoriesResult.json());
  setProducts(productsResult.json());

或者找出另一种方法将Response.Body调整为您可以操作的形式。 Check out the API reference for Response


要解析 Promise,您可以调用 promise.then(...),其中 promise 是从 返回的 Promise 对象fetch().

为此,我建议将两个提取分开,以便简化 promise 的解决,并可能使界面的其他部分更快地响应(即,如果一个提取先于另一个提取,您可以呈现这些结果,即使您没有另一个。即使您想等到两个部分都完成,您也可以根据 loading 的状态进行渲染。)

export const ProductsProvider = props => {
  const [loading, setLoading] = useState(true);

  const [categories, setCategories] = useState({});
  useEffect(() => {
    fetch('http://localhost:3000/api/categories')
      .then((response) => {
         setCategories(response.json());
      }
    setLoading(/* false only if categories AND product are not {} */);
  }, []);

  // Repeat the above, except for products

  return (
    <ProductsContext.Provider value={ { products, categories, loading } }>
      {props.children}
    </ProductsContext.Provider>
  );
}

关于javascript - 获取数据时使用 useEffect 和 useContext,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57845853/

相关文章:

javascript - 页面转换后的 JQueryMobile 内容跳转(使用数据位置 ="fixed")

javascript - 类型错误 : dispatch is not a function when using react-context api

reactjs - getServerSideProps 访问当前浏览器 url

routes - 无限数量的嵌套动态路由 Next.js

javascript - 如何在 next.config.js 文件中组合几个插件?

javascript - Instafeed/html 响应部分

javascript - CanvasRenderingContext2D.drawImage() 在大 Canvas 上的 Chrome 中非常慢

javascript - 如何访问 axios 加载的对象属性?

reactjs - Next.js 部署 : Node. js 与静态 HTML 导出?

javascript - 将函数调用的结果作为 javascript/node.js 中的函数进行调用