【问题标题】:useLocation state is coming nulluseLocation 状态变为空
【发布时间】:2023-01-11 17:03:14
【问题描述】:

我正在尝试调试我的应用程序。这是一个简单的应用程序,它从 spoonacular 中随机获取 api 图像,然后像 tinder 一样,您可以按“Yah”或“Nah”。当按下“Yah”时,它会推送到一个数组,并且应该在 Checkout 组件中显示该数组。我一直在尝试不同的方法,但没有任何效果。我使用了 useLocation,它工作了一分钟,然后状态变为空。

import React, { useState, useEffect } from "react";
import { Link } from "react-router-dom";
import "./Home.css"

const userFood = [
    "https://spoonacular.com/recipeImages/715544-556x370.jpg",
    "https://spoonacular.com/recipeImages/645978-556x370.jpg",
    "https://spoonacular.com/recipeImages/716279-556x370.jpg",
    "https://spoonacular.com/recipeImages/689453-556x370.jpg",
];


const Home = () => {
    const [food, setFood] = useState({});
    const apik = process.env.REACT_APP_FOOD_API_KEY;
    const foodUrl = `https://api.spoonacular.com/recipes/random?number=1&apiKey=${apik}`;

    useEffect(() => {
        urlFetch();
    },[]);

    const urlFetch = () => {
        fetch(foodUrl)
            .then((res) => {
                if (res.ok) {
                    return res.json();
                }
                throw res;
            })
            .then((json) => {
                console.log(json.recipes[0].image);
                setFood(json);
            })
            .catch((err) => console.log("something went wrong...", err));
    };

    const handleYah = () => {
        userFood.push(food.recipes[0].image);
    };
    console.log(userFood);

    return (
        <div className="home">

            {Object.keys(food).length ? (
                <img src={food.recipes[0].image} alt="Random Food" className="home__img" />
            ) : (
                "no images"
            )}
            <div className="home__buttons--container">
                <button className="home__yesno" id="home__nah" onClick={() => urlFetch()}>Nah</button>
                <Link
                    to={{
                        pathname: "/Checkout",
                        state: { userFood },
                    }}
                >
                    <button id="home__checkout">Checkout</button>
                </Link>
                <button className="home__yesno" id="home__yah" onClick={() => urlFetch() & handleYah()}>Yah</button>


            </div>
        </div >
    );
};

export default Home;
import React, { useState } from "react";
import { Link, useLocation } from "react-router-dom";
import "./Checkout.css";


const testBotFood = [
    "https://spoonacular.com/recipeImages/661365-556x370.jpg",
    "https://spoonacular.com/recipeImages/715544-556x370.jpg",
    "https://spoonacular.com/recipeImages/716279-556x370.jpg",
    "https://spoonacular.com/recipeImages/645978-556x370.jpg",
];

const Checkout = () => {
    let location = useLocation()
    console.log(location)
    // let userFoodCopy = location.state.userFood
    // console.log(userFoodCopy)
    // function arrayMatch(userFoodCopy, testBotFood) {
    //     const matchFood = [];
    //     for (let i = 0; i < userFoodCopy.length; i++) {
    //         for (let j = 0; j < testBotFood.length; j++) {
    //             if (userFoodCopy[i] === testBotFood[j]) {
    //                 matchFood.push(userFoodCopy[i]);
    //             }
    //         }
    //     }
    //     return matchFood;
    // }
    // const arrayOfMatches = arrayMatch(userFoodCopy, testBotFood);


    // function arrayNotMatch(userFoodCopy, testBotFood) {
    //     const noMatchFood = [];
    //     for (let i = 0; i < userFoodCopy.length; i++) {
    //         for (let j = 0; j < testBotFood.length; j++) {
    //             if (
    //                 userFoodCopy[i] !== testBotFood[j] &&
    //                 !noMatchFood.includes(userFoodCopy[i])
    //             ) {
    //                 noMatchFood.push(userFoodCopy[i]);
    //             }
    //         }
    //     }
    //     return noMatchFood;
    // }
    // //   console.log(arrayNotMatch(userFoodCopy, testBotFood));

    // return (
    //     <div className="checkout">
    //         {/* <nav>
    //           <Link to="/" style={{textDecoration:"none"}}>
    //             <button className="headerButton" id="backButton">
    //               &#9665;
    //             </button>
    //           </Link>
    //         </nav> */}
    //         <h2>Match</h2>
    //         <div className="checkout__checkMatch">
    //             {arrayOfMatches.map((copyFood) => (
    //                 <div className="checkout__images--grid">
    //                     {/* <Link
    //               to={{
    //                 pathname: "/Messages",
    //                 state: { arrayOfMatches },
    //               }}
    //               key={copyFood}
    //             > */}
    //                     <img
    //                         src={copyFood}
    //                         alt="userPics"
    //                         key={copyFood}
    //                         className="checkout__images"
    //                     />
    //                     {/* </Link> */}
    //                 </div>
    //             ))}
    //         </div>
    //         <h2>Favorites</h2>
    //         <div className="checkout__checkMatch">
    //             {arrayNotMatch(userFoodCopy, testBotFood).map((noMatch) => (
    //                 <div className="checkout__images--grid" >
    //                     <img src={noMatch} alt="userPics" key={noMatch} className="checkout__images" />
    //                 </div>
    //             ))}
    //         </div>
    //     </div>
    // );
};

export default Checkout;

这是应用程序根级别

import './App.css';
import React, { useState } from "react"
import { Route, Routes } from "react-router-dom";
import Header from './components/Header/Header.jsx';
// import Menu from './components/Menu/Menu.jsx';
import Home from './components/Home/Home.jsx';
import Checkout from './components/Checkout/Checkout.jsx'


function App() {

  return (
    <div className="app">
      <Header />

      <Routes>
        {/* <Route exact path="/Menu" element={<Menu />} /> */}
          <Route exact path="/" element={<Home />} />
          <Route exact path='/Checkout' element={<Checkout />} />
      </Routes>
    </div>
  );
}

export default App;

我认为 index.js 编码正确,但我会粘贴它以防万一

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { BrowserRouter as Router } from 'react-router-dom'
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <Router>
      <App />
    </Router>
  </React.StrictMode>
);

任何建议都会很棒!我觉得这是一个简单的修复,但我似乎无法弄清楚。

谢谢你,Som Shekhar Mukherjee。我一开始就应该这样做。这是github页面链接https://hongssam9.github.io/Lood/ 出于某种原因,它不会让我直接进入主页。

【问题讨论】:

  • 为其他人创建一个最小的可重现示例以进行调试,使您的代码可在 SO 上运行或共享指向 codesandbox 的链接。像这样调试非常困难。
  • @SomShekharMukherjee 我在帖子上发布了链接。

标签: javascript reactjs


【解决方案1】:

我认为您在 Checkout.js 中的大部分代码都依赖于 UserFoodCopy 数组,该数组未被 useLocation() 感染。

这可以通过将 let userFoodCopy = location.state.userFood; 更改为 let userFoodCopy = location.state; 来解决

我想一旦你获得了 userFoodCopy,你就可以在Checkout.js 中查看以下所有功能。

也可以参考这个article

【讨论】:

  • 我试过了。我想先通过 console.log(location) 检查位置以查看状态是否可用,但状态变为空,这阻止我访问来自 Home 组件的任何数据。
【解决方案2】:

我也在为此苦苦挣扎。我在GitHub Issue中找到了答案。事实证明状态现在直接作为 prop 传递,而不是作为 to prop 的属性。 在您的代码中,更改此行。

<Link to={{
           pathname: "/Checkout",
           state: { userFood },
         }}
>

到:

<Link
      to={{
      pathname: "/Checkout",              
      }}
      state= { userFood }
 >

我希望你明白我的意思。编码愉快!

【讨论】:

    猜你喜欢
    • 2020-09-01
    • 1970-01-01
    • 2021-09-14
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 2013-03-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多