如何在 React 中通过 Link 传递道具(this.props.location 未定义)
How to pass props via Link in React (this.props.location is undefined)
我正在 React 中创建一个食谱研究项目。在主页上,我按 'search recipe' 它会为我找到它们,然后 'view recipe' 它应该会显示一些我必须决定的数据。当我在组件中执行 console.log (this.props) 时,它 returns 我没有状态值的所有对象,因此我无法访问数据。请你帮助我好吗?我把代码留给你以便更好地理解。
import logo from "./logo.svg";
import "./App.css";
import React, { useState } from "react";
import MealList from "./MealList";
function App() {
const [mealData, setMealData] = useState(null);
/*const [calories, setCalories] = useState(2000)*/
const [food, setFood] = useState("");
function handleChange(e) {
setFood(e.target.value);
}
function getMealData() {
fetch(
`https://api.spoonacular.com/recipes/complexSearch?apiKey=1d66c25bc4bb4ac288efecc0f2c4c4b8&diet=vegetarian`
) /* &addRecipeInformation=true */
.then((response) => response.json())
.then((data) => {
setMealData(data);
})
.catch(() => {
console.log("error");
});
}
return (
<div className="App">
<section className="controls">
{/*<input type="number" placeholder='Calories (e.g. 2000)' onChange={handleChange}/>*/}
<input type="string" placeholder="food" onChange={handleChange} />
</section>
<button onClick={getMealData}> CERCA PASTI VEGETARIANI</button>
{mealData && <MealList mealData={mealData}/>}
</div>
);
}
export default App;
import React from "react";
import Meal from "./Meal";
export default function MealList({ mealData }) {
return (
<main>
<section className="meals">
{mealData.results.map((meal) => {
return <Meal key={meal.id} meal={meal} />;
})}
</section>
</main>
);
}
import React, {useState, useEffect} from 'react'
import {Link} from 'react-router-dom'
export default function Meal({meal}) {
const [imageUrl, setImageUrl] = useState("");
useEffect(()=>{
fetch(`https://api.spoonacular.com/recipes/${meal.id}/information?apiKey=1d66c25bc4bb4ac288efecc0f2c4c4b8`)
.then((response)=>response.json())
.then((data)=>{
setImageUrl(data.image)
})
.catch(()=>{
console.log("errorn in meal js fetch")
})
}, [meal.id])
const location = {
pathname: '/somewhere',
state: { fromDashboard: true }
}
return (
<article>
<h1>{meal.title}</h1>
<img src={imageUrl } alt="recipe"></img>
<div>
<button className='recipeButtons'>
<Link to={{
pathname: `/recipe/${meal.id}`,
state: {meal: meal.id}}}>
Guarda Ricetta
</Link>
</button>
</div>
</article>
)
}
import React from "react";
class Recipe extends React.Component{
render() {
console.log(this.props)
return(
<div>class Recipe extends React.Component</div>
)
}
}
export default Recipe;
这是 console.log(this.props) 的结果(this.props.location 未定义):
this props
你没有展示你是如何渲染 的,所以我一眼就看不出问题出在哪里。
但是,您不需要将位置作为道具传递。 React-Router 包含一个钩子 useLocation
,可以从任何功能组件调用它。您可以将 Recipe 更改为函数组件并使用:
import { useLocation } from 'react-router-dom'
/* ... */
function Recipe(props) {
const location = useLocation()
/* ... */
}
预计到达时间:
检查 <Link/>
和 To
的类型定义,the API reference on reactrouter.com 似乎是错误的。 To
实际上是 string | Partial<Path>
,其中 Path
是:
interface Path {
/**
* A URL pathname, beginning with a /.
*
* @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#location.pathname
*/
pathname: Pathname;
/**
* A URL search string, beginning with a ?.
*
* @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#location.search
*/
search: Search;
/**
* A URL fragment identifier, beginning with a #.
*
* @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#location.hash
*/
hash: Hash;
}
这就是从未设置状态的原因。要在 link 中设置状态,您需要将其作为 React prop 包含在内,如下所示:
<Link to={`/recipe/${meal.id}`} state={{ meal: meal.id }}>Guarda Ricetta</Link>
您可以使用带有 React 路由器挂钩的功能组件来访问该位置,而不是 class 组件
import { useLocation } from "react-router-dom";
export default function Recipe () {
const location = useLocation();
return (
<div> Recipe </div
)
}
我正在 React 中创建一个食谱研究项目。在主页上,我按 'search recipe' 它会为我找到它们,然后 'view recipe' 它应该会显示一些我必须决定的数据。当我在组件中执行 console.log (this.props) 时,它 returns 我没有状态值的所有对象,因此我无法访问数据。请你帮助我好吗?我把代码留给你以便更好地理解。
import logo from "./logo.svg";
import "./App.css";
import React, { useState } from "react";
import MealList from "./MealList";
function App() {
const [mealData, setMealData] = useState(null);
/*const [calories, setCalories] = useState(2000)*/
const [food, setFood] = useState("");
function handleChange(e) {
setFood(e.target.value);
}
function getMealData() {
fetch(
`https://api.spoonacular.com/recipes/complexSearch?apiKey=1d66c25bc4bb4ac288efecc0f2c4c4b8&diet=vegetarian`
) /* &addRecipeInformation=true */
.then((response) => response.json())
.then((data) => {
setMealData(data);
})
.catch(() => {
console.log("error");
});
}
return (
<div className="App">
<section className="controls">
{/*<input type="number" placeholder='Calories (e.g. 2000)' onChange={handleChange}/>*/}
<input type="string" placeholder="food" onChange={handleChange} />
</section>
<button onClick={getMealData}> CERCA PASTI VEGETARIANI</button>
{mealData && <MealList mealData={mealData}/>}
</div>
);
}
export default App;
import React from "react";
import Meal from "./Meal";
export default function MealList({ mealData }) {
return (
<main>
<section className="meals">
{mealData.results.map((meal) => {
return <Meal key={meal.id} meal={meal} />;
})}
</section>
</main>
); }
import React, {useState, useEffect} from 'react'
import {Link} from 'react-router-dom'
export default function Meal({meal}) {
const [imageUrl, setImageUrl] = useState("");
useEffect(()=>{
fetch(`https://api.spoonacular.com/recipes/${meal.id}/information?apiKey=1d66c25bc4bb4ac288efecc0f2c4c4b8`)
.then((response)=>response.json())
.then((data)=>{
setImageUrl(data.image)
})
.catch(()=>{
console.log("errorn in meal js fetch")
})
}, [meal.id])
const location = {
pathname: '/somewhere',
state: { fromDashboard: true }
}
return (
<article>
<h1>{meal.title}</h1>
<img src={imageUrl } alt="recipe"></img>
<div>
<button className='recipeButtons'>
<Link to={{
pathname: `/recipe/${meal.id}`,
state: {meal: meal.id}}}>
Guarda Ricetta
</Link>
</button>
</div>
</article>
)
}
import React from "react";
class Recipe extends React.Component{
render() {
console.log(this.props)
return(
<div>class Recipe extends React.Component</div>
)
}
}
export default Recipe;
这是 console.log(this.props) 的结果(this.props.location 未定义): this props
你没有展示你是如何渲染
但是,您不需要将位置作为道具传递。 React-Router 包含一个钩子 useLocation
,可以从任何功能组件调用它。您可以将 Recipe 更改为函数组件并使用:
import { useLocation } from 'react-router-dom'
/* ... */
function Recipe(props) {
const location = useLocation()
/* ... */
}
预计到达时间:
检查 <Link/>
和 To
的类型定义,the API reference on reactrouter.com 似乎是错误的。 To
实际上是 string | Partial<Path>
,其中 Path
是:
interface Path {
/**
* A URL pathname, beginning with a /.
*
* @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#location.pathname
*/
pathname: Pathname;
/**
* A URL search string, beginning with a ?.
*
* @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#location.search
*/
search: Search;
/**
* A URL fragment identifier, beginning with a #.
*
* @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#location.hash
*/
hash: Hash;
}
这就是从未设置状态的原因。要在 link 中设置状态,您需要将其作为 React prop 包含在内,如下所示:
<Link to={`/recipe/${meal.id}`} state={{ meal: meal.id }}>Guarda Ricetta</Link>
您可以使用带有 React 路由器挂钩的功能组件来访问该位置,而不是 class 组件
import { useLocation } from "react-router-dom";
export default function Recipe () {
const location = useLocation();
return (
<div> Recipe </div
)
}