如何使用 React 正确设置 react-router-dom 链接
How to set properly react-router-dom links with React
由于缺乏经验,我一直在为我的第一个个人项目而苦苦挣扎,这是我遇到的麻烦:
我需要设置一个 Link 组件(属于 react-router-dom),当我单击按钮时它会将我带到另一个新页面。认为我需要将选择传递给 link(和上下文)id,以便我可以从 API 获取数据,但我不知道如何让它工作。这是按钮 link 组件:
Model.jsx
import React, { useState, useContext } from 'react';
import { BrowserRouter as Router, Switch, Route, Link, Redirect } from 'react-router-dom';
import FileModel from "../FileModel/FileModel";
import { ModelsContext } from "../../context/ModelsContext";
const Model = ({modelo}) => {
const { id, name, year, price, photo } = modelo;
const { guardarModelo } = useContext(ModelsContext);
const [display, setDisplay] = useState("btn-notdisplayed");
const showButton = e => {
e.preventDefault();
setDisplay("btn-displayed");
};
const hideButton = e => {
e.preventDefault();
setDisplay("btn-notdisplayed");
};
return (
<div
className="card"
onMouseEnter={e => showButton(e)}
onMouseLeave={e => hideButton(e)}
>
<div className="card-body">
<p className="card-name">{name}</p>
<p className="card-yearprice">{year} | $ {price}</p>
</div>
<img src={`https://challenge.agenciaego.tech${photo}`} className="card-image" alt={`Imagen de ${name}`} />
<Router>
<button
type="button"
className={display}
onClick={() => {
guardarModelo(modelo);
}}
><Link to={`/models/${modelo.id}`}>Ver Modelo</Link>
</button>
<Switch>
<Route exact path={`/models/${modelo.id}`} component={FileModel} />
</Switch>
</Router>
</div>
);
}
export default Model;
然后我从上下文中获取了数据:
ModelsContext.jsx
import React, { createContext, useState, useEffect } from 'react';
export const ModelsContext = createContext();
const ModelsProvider = (props) => {
//State de modelos
const [ modelo, guardarModelo ] = useState({});
const [ modelos, guardarModelos ] = useState([]);
const [ allModelos, guardarAllModelo ] = useState([]);
//Cargar un modelo
useEffect(() => {
const consultarAPI = async () => {
const api = await fetch("https://challenge.agenciaego.tech/models");
const modelos = await api.json();
const api2 = await fetch(`https://challenge.agenciaego.tech/models/${id}`);
const modelo = await api2.json();
guardarAllModelo(modelos);
guardarModelos(modelos);
guardarModelo(modelo);
}
consultarAPI()
}, []);
return (
<ModelsContext.Provider
value={{
allModelos,
modelo,
modelos,
guardarModelo,
guardarModelos
}}
>
{props.children}
</ModelsContext.Provider>
)
}
export default ModelsProvider;
最后,我得到了App.js,我从中路由了主要组件,我的想法是将Link作为一个名为“FileModel.jsx”的新组件子组件因此维护 Navbar 组件。
App.js
import React from "react";
import Navbar from "./components/Nav/Navbar";
import Models from "./components/Models/Models";
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';
import Logo from "./assets/img/logo.png";
import ModelsProvider from "./context/ModelsContext";
import ModelFooter from "./components/Models/ModelFooter";
function App() {
return (
<ModelsProvider>
<Router>
<nav className="navbar">
<img src={Logo} className="logo" alt="Ego Logo" />
<div className="menu-container">
<Link to={'/models'} className="menu-items">Modelos</Link>
<a className="menu-items">Ficha de modelo</a>
</div>
<div className="bottom-line"></div>
</nav>
<Switch>
<Route exact path='/models' component={Models} />
</Switch>
</Router>
<Navbar />
<ModelFooter />
</ModelsProvider>
);
}
export default App;
这是目前的文件Model.jsx:
import React, { useContext } from 'react';
import Navbar from "../Nav/Navbar";
import { ModelsContext } from "../../context/ModelsContext";
const FileModel = () => {
const { modelo } = useContext(ModelsContext);
console.log(modelo.id);
return (
<Navbar />
);
}
export default FileModel;
希望把我的问题解释清楚,非常感谢各位爱心人士!
干杯!
Ps:也许您可以找到一些需要重构的东西(稍后我需要检查我的代码),如果您找到类似的东西,我们将不胜感激!
更新
由于Linda的推荐,我将两个上下文合并为一个,并更改了我之前写的一些代码行,我无法设置状态将solo模型传递给fileModel组件,Link仍然不工作,我在想一个可以做到的功能,我做了另一个状态,一个单一的模型,但是当我点击按钮时我得到一个错误和未定义,因为 Idk 如何在状态中设置 Id 并传递它对于 API 调用,终端说 id in const api2 = await fetch(https://challenge.agenciaego.tech/models/${id}
);未定义。
我终于解决了我的问题!!!我不得不在我的组件之间重新定位一些元素,以使 api 上下文获取 id 并将其传递给 FileModel 组件,并将 Link 路由器更改为 App.js,这就是我的方式获取解决方案:
App.js
import React from "react";
import Navbar from "./components/Nav/Navbar";
import Models from "./components/Models/Models";
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';
import Logo from "./assets/img/logo.png";
import ModelsProvider from "./context/ModelsContext";
import ModelFooter from "./components/Models/ModelFooter";
import FileModel from "./components/FileModel/FileModel";
function App() {
return (
<ModelsProvider>
<Router>
<nav className="navbar">
<img src={Logo} className="logo" alt="Ego Logo" />
<div className="menu-container">
<Link to={'/models'} className="menu-items">Modelos</Link>
<Link to={`/models/1`} className="menu-items">Ficha del Modelo</Link>
</div>
<div className="bottom-line"></div>
</nav>
<Switch>
<Route exact path='/models' component={Models} />
<Route exact path='/models' component={Models} />
</Switch>
</Router>
<Navbar />
<FileModel />
<ModelFooter />
</ModelsProvider>
);
}
export default App;
Modelscontext.jsx
import React, { createContext, useState, useEffect } from 'react';
export const ModelsContext = createContext();
const ModelsProvider = (props) => {
//State de modelos
const [ modelo, guardarModelo ] = useState([]);
const [ modelos, guardarModelos ] = useState([]);
const [ allModelos, guardarAllModelo ] = useState([]);
const { id } = modelo;
//Cargar un modelo
useEffect(() => {
const consultarAPI = async () => {
const api = await fetch("https://challenge.agenciaego.tech/models");
const modelos = await api.json();
const api2 = await fetch(`https://challenge.agenciaego.tech/models/${id}`);
const modelo = await api2.json();
guardarAllModelo(modelos);
guardarModelos(modelos);
guardarModelo(modelo);
}
consultarAPI()
}, [modelo.id]);
return (
<ModelsContext.Provider
value={{
allModelos,
modelo,
modelos,
guardarModelo,
guardarModelos
}}
>
{props.children}
</ModelsContext.Provider>
)
}
export default ModelsProvider;
Model.js
import React, { useState, useContext } from 'react';
import { Link } from 'react-router-dom';
import { ModelsContext } from "../../context/ModelsContext";
const Model = ({modelo}) => {
const { name, year, price, photo } = modelo;
const { guardarModelo } = useContext(ModelsContext);
const [display, setDisplay] = useState("btn-notdisplayed");
const showButton = e => {
e.preventDefault();
setDisplay("btn-displayed");
};
const hideButton = e => {
e.preventDefault();
setDisplay("btn-notdisplayed");
};
return (
<div
className="card"
onMouseEnter={e => showButton(e)}
onMouseLeave={e => hideButton(e)}
>
<div className="card-body">
<p className="card-name">{name}</p>
<p className="card-yearprice">{year} | $ {price}</p>
</div>
<img src={`https://challenge.agenciaego.tech${photo}`} className="card-image" alt={`Imagen de ${name}`} />
<Link to={`/models/${modelo.id}`}><button
type="button"
className={display}
onClick={() => {
guardarModelo(modelo);
}}
>Ver Modelo
</button></Link>
</div>
);
}
export default Model;
文件Model.js(到目前为止...)
import React, { useContext } from 'react';
import Navbar from "../Nav/Navbar";
import { ModelsContext } from "../../context/ModelsContext";
const FileModel = () => {
const { modelo } = useContext(ModelsContext);
const { photo, name } = modelo;
return (
<>
<Navbar />
<section>
<img src={`https://challenge.agenciaego.tech${photo}`} alt={`Imagen de ${name}`}/>
</section>
</>
);
}
export default FileModel;
感谢 Linda 给我重构上下文的输入!干杯!
由于缺乏经验,我一直在为我的第一个个人项目而苦苦挣扎,这是我遇到的麻烦:
我需要设置一个 Link 组件(属于 react-router-dom),当我单击按钮时它会将我带到另一个新页面。认为我需要将选择传递给 link(和上下文)id,以便我可以从 API 获取数据,但我不知道如何让它工作。这是按钮 link 组件:
Model.jsx
import React, { useState, useContext } from 'react';
import { BrowserRouter as Router, Switch, Route, Link, Redirect } from 'react-router-dom';
import FileModel from "../FileModel/FileModel";
import { ModelsContext } from "../../context/ModelsContext";
const Model = ({modelo}) => {
const { id, name, year, price, photo } = modelo;
const { guardarModelo } = useContext(ModelsContext);
const [display, setDisplay] = useState("btn-notdisplayed");
const showButton = e => {
e.preventDefault();
setDisplay("btn-displayed");
};
const hideButton = e => {
e.preventDefault();
setDisplay("btn-notdisplayed");
};
return (
<div
className="card"
onMouseEnter={e => showButton(e)}
onMouseLeave={e => hideButton(e)}
>
<div className="card-body">
<p className="card-name">{name}</p>
<p className="card-yearprice">{year} | $ {price}</p>
</div>
<img src={`https://challenge.agenciaego.tech${photo}`} className="card-image" alt={`Imagen de ${name}`} />
<Router>
<button
type="button"
className={display}
onClick={() => {
guardarModelo(modelo);
}}
><Link to={`/models/${modelo.id}`}>Ver Modelo</Link>
</button>
<Switch>
<Route exact path={`/models/${modelo.id}`} component={FileModel} />
</Switch>
</Router>
</div>
);
}
export default Model;
然后我从上下文中获取了数据:
ModelsContext.jsx
import React, { createContext, useState, useEffect } from 'react';
export const ModelsContext = createContext();
const ModelsProvider = (props) => {
//State de modelos
const [ modelo, guardarModelo ] = useState({});
const [ modelos, guardarModelos ] = useState([]);
const [ allModelos, guardarAllModelo ] = useState([]);
//Cargar un modelo
useEffect(() => {
const consultarAPI = async () => {
const api = await fetch("https://challenge.agenciaego.tech/models");
const modelos = await api.json();
const api2 = await fetch(`https://challenge.agenciaego.tech/models/${id}`);
const modelo = await api2.json();
guardarAllModelo(modelos);
guardarModelos(modelos);
guardarModelo(modelo);
}
consultarAPI()
}, []);
return (
<ModelsContext.Provider
value={{
allModelos,
modelo,
modelos,
guardarModelo,
guardarModelos
}}
>
{props.children}
</ModelsContext.Provider>
)
}
export default ModelsProvider;
最后,我得到了App.js,我从中路由了主要组件,我的想法是将Link作为一个名为“FileModel.jsx”的新组件子组件因此维护 Navbar 组件。
App.js
import React from "react";
import Navbar from "./components/Nav/Navbar";
import Models from "./components/Models/Models";
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';
import Logo from "./assets/img/logo.png";
import ModelsProvider from "./context/ModelsContext";
import ModelFooter from "./components/Models/ModelFooter";
function App() {
return (
<ModelsProvider>
<Router>
<nav className="navbar">
<img src={Logo} className="logo" alt="Ego Logo" />
<div className="menu-container">
<Link to={'/models'} className="menu-items">Modelos</Link>
<a className="menu-items">Ficha de modelo</a>
</div>
<div className="bottom-line"></div>
</nav>
<Switch>
<Route exact path='/models' component={Models} />
</Switch>
</Router>
<Navbar />
<ModelFooter />
</ModelsProvider>
);
}
export default App;
这是目前的文件Model.jsx:
import React, { useContext } from 'react';
import Navbar from "../Nav/Navbar";
import { ModelsContext } from "../../context/ModelsContext";
const FileModel = () => {
const { modelo } = useContext(ModelsContext);
console.log(modelo.id);
return (
<Navbar />
);
}
export default FileModel;
希望把我的问题解释清楚,非常感谢各位爱心人士!
干杯!
Ps:也许您可以找到一些需要重构的东西(稍后我需要检查我的代码),如果您找到类似的东西,我们将不胜感激!
更新
由于Linda的推荐,我将两个上下文合并为一个,并更改了我之前写的一些代码行,我无法设置状态将solo模型传递给fileModel组件,Link仍然不工作,我在想一个可以做到的功能,我做了另一个状态,一个单一的模型,但是当我点击按钮时我得到一个错误和未定义,因为 Idk 如何在状态中设置 Id 并传递它对于 API 调用,终端说 id in const api2 = await fetch(https://challenge.agenciaego.tech/models/${id}
);未定义。
我终于解决了我的问题!!!我不得不在我的组件之间重新定位一些元素,以使 api 上下文获取 id 并将其传递给 FileModel 组件,并将 Link 路由器更改为 App.js,这就是我的方式获取解决方案:
App.js
import React from "react";
import Navbar from "./components/Nav/Navbar";
import Models from "./components/Models/Models";
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';
import Logo from "./assets/img/logo.png";
import ModelsProvider from "./context/ModelsContext";
import ModelFooter from "./components/Models/ModelFooter";
import FileModel from "./components/FileModel/FileModel";
function App() {
return (
<ModelsProvider>
<Router>
<nav className="navbar">
<img src={Logo} className="logo" alt="Ego Logo" />
<div className="menu-container">
<Link to={'/models'} className="menu-items">Modelos</Link>
<Link to={`/models/1`} className="menu-items">Ficha del Modelo</Link>
</div>
<div className="bottom-line"></div>
</nav>
<Switch>
<Route exact path='/models' component={Models} />
<Route exact path='/models' component={Models} />
</Switch>
</Router>
<Navbar />
<FileModel />
<ModelFooter />
</ModelsProvider>
);
}
export default App;
Modelscontext.jsx
import React, { createContext, useState, useEffect } from 'react';
export const ModelsContext = createContext();
const ModelsProvider = (props) => {
//State de modelos
const [ modelo, guardarModelo ] = useState([]);
const [ modelos, guardarModelos ] = useState([]);
const [ allModelos, guardarAllModelo ] = useState([]);
const { id } = modelo;
//Cargar un modelo
useEffect(() => {
const consultarAPI = async () => {
const api = await fetch("https://challenge.agenciaego.tech/models");
const modelos = await api.json();
const api2 = await fetch(`https://challenge.agenciaego.tech/models/${id}`);
const modelo = await api2.json();
guardarAllModelo(modelos);
guardarModelos(modelos);
guardarModelo(modelo);
}
consultarAPI()
}, [modelo.id]);
return (
<ModelsContext.Provider
value={{
allModelos,
modelo,
modelos,
guardarModelo,
guardarModelos
}}
>
{props.children}
</ModelsContext.Provider>
)
}
export default ModelsProvider;
Model.js
import React, { useState, useContext } from 'react';
import { Link } from 'react-router-dom';
import { ModelsContext } from "../../context/ModelsContext";
const Model = ({modelo}) => {
const { name, year, price, photo } = modelo;
const { guardarModelo } = useContext(ModelsContext);
const [display, setDisplay] = useState("btn-notdisplayed");
const showButton = e => {
e.preventDefault();
setDisplay("btn-displayed");
};
const hideButton = e => {
e.preventDefault();
setDisplay("btn-notdisplayed");
};
return (
<div
className="card"
onMouseEnter={e => showButton(e)}
onMouseLeave={e => hideButton(e)}
>
<div className="card-body">
<p className="card-name">{name}</p>
<p className="card-yearprice">{year} | $ {price}</p>
</div>
<img src={`https://challenge.agenciaego.tech${photo}`} className="card-image" alt={`Imagen de ${name}`} />
<Link to={`/models/${modelo.id}`}><button
type="button"
className={display}
onClick={() => {
guardarModelo(modelo);
}}
>Ver Modelo
</button></Link>
</div>
);
}
export default Model;
文件Model.js(到目前为止...)
import React, { useContext } from 'react';
import Navbar from "../Nav/Navbar";
import { ModelsContext } from "../../context/ModelsContext";
const FileModel = () => {
const { modelo } = useContext(ModelsContext);
const { photo, name } = modelo;
return (
<>
<Navbar />
<section>
<img src={`https://challenge.agenciaego.tech${photo}`} alt={`Imagen de ${name}`}/>
</section>
</>
);
}
export default FileModel;
感谢 Linda 给我重构上下文的输入!干杯!