Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/473.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在获取数据时使用useEffect和useContext_Javascript_Reactjs_Next.js - Fatal编程技术网

Javascript 在获取数据时使用useEffect和useContext

Javascript 在获取数据时使用useEffect和useContext,javascript,reactjs,next.js,Javascript,Reactjs,Next.js,我正在尝试学习如何使用React的上下文API和挂钩,并尝试在使用fetch()的项目中工作 当同时使用这两种方法时,我会得到请求,但除了加载之外,我无法得到我设置的数据 import React,{useState, createContext} from 'react'; export const ProductsContext = createContext(); export const ProductsProvider = props => { const [cate

我正在尝试学习如何使用React的上下文API和挂钩,并尝试在使用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>
    );
}
正如您所看到的,没有数据,只有加载更改


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

在随意阅读时,React.useContext()看起来是可用的。我看到的问题是,React状态变量、
categories
product
被设置为来自
fetch()
的响应,并且根据,fetch返回一个从承诺解析为响应的值,这不是您想要的

但这很接近!你应该这样做

  setCategories(categoriesResult.json());
  setProducts(productsResult.json());
或者想出另一种方法将
Response.Body
按摩成一种你可以操纵的形式


要解析承诺,请调用
promise。然后(…)
其中
promise
是从
fetch()
返回的promise对象

为此,我建议将两个回迁分开,以便简化承诺的解析,并可能使接口的其他部分更快响应(也就是说,如果一个提取在另一个提取之前,即使没有另一个提取,也可以呈现这些结果。即使要等到两个部分都完成,也可以使呈现取决于加载的状态。)

export const ProductsProvider=props=>{
const[loading,setLoading]=useState(true);
const[categories,setCategories]=useState({});
useffect(()=>{
取('http://localhost:3000/api/categories')
。然后((响应)=>{
setCategories(response.json());
}
setLoading(/*仅当类别和产品不是{}*/)时为false;
}, []);
//重复上述步骤,产品除外
返回(
{props.children}
);
}

谢谢!但是,当console.log响应时,
{console.log(产品、类别、加载)}
我得到了数据,但它在
[[PromiseValue]]
。我如何从中访问数据?是的,您已将两个承诺包装成另一个承诺,因此您需要解决外部承诺和内部承诺,坦率地说,这会使事情变得不必要的复杂。有关简单解决方案,请参阅更新的答案。
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;
{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
  setCategories(categoriesResult.json());
  setProducts(productsResult.json());
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>
  );
}