reactjs 使用Context时,如何将API返回的数据从一个组件传递到另一个组件?[duplicate]

5ssjco0h  于 2023-01-30  发布在  React
关注(0)|答案(1)|浏览(188)
    • 此问题在此处已有答案**:

The useState set method is not reflecting a change immediately(15个答案)
2天前关闭。
我正在将从Spoonacular(即www.example.com)返回的数据从SearchRecipes传递到DisplayRecipes。由于某种原因,Recipes被记录为空。response.data from SearchRecipes to DisplayRecipes. For some reason recipe is being logged as empty.
我附上所有相关代码如下:

    • 搜索配方**
import React, { useContext, useState, useEffect } from "react";
import axios from "axios";
import { IngredientsContext } from "../contexts/ingredientsContext";
import DisplayRecipes from "./DisplayRecipes";
import { RecipesContext } from "../contexts/recipesContext";

const URL = "https://api.spoonacular.com/recipes/findByIngredients";
const APIKey = "MyAPIKey";

const SearchRecipes = (props) => {
  const [selectedIngredients, setSelectedIngredients] =
    useContext(IngredientsContext);
  const [recipes, setRecipes] = useContext(RecipesContext);

  const handleIngredientClick = (ingredient) => {
    setSelectedIngredients(selectedIngredients.filter((i) => i !== ingredient));
  };

  const handleClick = async () => {
    try {
      const response = await axios.get(
        `${URL}?ingredients=${selectedIngredients.join(",+")}&apiKey=${APIKey}`
      );
      setRecipes(response.data);
      window.open("http://localhost:3000/displayRecipes");
      console.log(recipes);
    } catch (error) {
      console.error(error);
    }
  };

  return (
    <RecipesContext.Provider value={recipes}>
      <div className="pb-5 pt-10 ">
        <div>
          <p className="font-[Poppins] pb-4 font-semibold text-[#464646]">
            My Ingredients
          </p>
          <p
            className={`cursor-pointer ${
              selectedIngredients.length > 0 ? "pb-4" : ""
            }`}
          >
            {selectedIngredients.map((ingredient, index) => (
              <span
                key={index}
                pb-4
                onClick={() => handleIngredientClick(ingredient)}
              >
                {ingredient},
              </span>
            ))}
          </p>
          <div>
            <button
              className="bg-[#ffc107] px-6 rounded-md font-medium font-[Poppins] py-2 text-[1rem]"
              onClick={handleClick}
            >
              Find a recipe
            </button>
          </div>

          {/* {recipes && <DisplayRecipes recipes={recipes} />} */}
        </div>
      </div>
    </RecipesContext.Provider>
  );
};

export default SearchRecipes;
    • 显示配方**
import { RecipesContext } from "../contexts/recipesContext";

const DisplayRecipes = (props) => {
  const [recipes] = useContext(RecipesContext);
  console.log(recipes);
  useEffect(() => {
    document.body.classList.add("page-styles");
    return () => {
      document.body.classList.remove("page-styles");
    };
  }, []);
  return (
    <div>
      <div className="mt-28 ml-4">
        <h1
          className="font-[Acme] text-5xl text-left text-[#ffc107] "
          style={{
            textAlign: "left !important",
            marginLeft: "10px !important",
          }}
        >
          Recipes
        </h1>
        <div></div>
      </div>
    </div>
  );
};

export default DisplayRecipes;
    • 应用程序**
import NavBar from "./components/NavBar.jsx";
import MainGrid from "./components/MainGrid.jsx";
import { IngredientsContext } from "./contexts/ingredientsContext.js";
import DisplayRecipes from "./components/DisplayRecipes.jsx";
import { Routes, Route } from "react-router-dom";
import { useNavigate } from "react-router-dom";
import { RecipesContextProvider } from "./contexts/recipesContext.js";

const App = () => {
  const [selectedIngredients, setSelectedIngredients] = useState([]);
  const [showRecipes, setShowRecipes] = useState(false);

  const handleRecipeClick = () => {
    setShowRecipes(true);
    window.open("http://localhost:3000/displayRecipes");
  };

  return (
    <RecipesContextProvider>
      {" "}
      <div>
        <IngredientsContext.Provider
          value={[selectedIngredients, setSelectedIngredients]}
        >
          <NavBar />
          <Routes>
            <Route
              path="/"
              element={<MainGrid handleRecipeClick={handleRecipeClick} />}
            />
            <Route path="/displayRecipes" element={<DisplayRecipes />} />
          </Routes>
        </IngredientsContext.Provider>
      </div>
    </RecipesContextProvider>
  );
};

export default App;
    • 接收方上下文. js**
export const RecipesContext = createContext();

export const RecipesContextProvider = (props) => {
  const [recipes, setRecipes] = useState([]);

  return (
    <RecipesContext.Provider value={[recipes, setRecipes]}>
      {props.children}
    </RecipesContext.Provider>
  );
};

我是一个非常新的React。这是我在这里的第一个问题,所以请原谅格式。

ncgqoxb0

ncgqoxb01#

查看应用的结构时,您会注意到有两个独立的RecipesContext提供程序:

<RecipesContextProvider> // from App
  <Route>
    <SearchRecipes>
        <RecipesContext.Provider> // from SearchRecipes
            <DisplayRecipe>

现在SearchRecipesApp中定义的上下文上调用setRecipes。但是,DisplayRecipe从'SearchRecipes'中定义的上下文获取其recipes
每个上下文都维护自己的状态,并且因为在SearchRecipes中打开的上下文是空的,所以您会遇到以下问题:-)。

相关问题