由于缺乏经验,我一直在挣扎我的第一个独奏作品,这是我遇到的麻烦:
我需要设置一个(react-router-dom)的链接组件,单击该按钮后,它会将我带到另一个新页面。考虑到选择需要传递给链接(和上下文)id,以便可以从API提取数据,但是我不知道如何使它起作用。这是按钮链接组件:
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,其想法是将名为“ 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;
到目前为止,这是fileModel.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;
我希望能清楚地说明我的问题,非常感谢所有关心我的人!
干杯!
附:也许您可以找到一些要重构的东西(稍后我将需要检查我的代码),如果您发现类似的东西,将不胜感激!
更新
由于Linda的建议,我将两个上下文合并为一个,并更改了我之前编写的代码的几行,因此我无法设置将单独模型传递给fileModel组件的状态,并且链接仍然无法正常工作,我在考虑一个函数可以做到的是,我创建了另一个状态,一个单一的模型,但是当我单击按钮时,我得到了一个错误且未定义,因为Idk如何将Id设置为状态并将其传递给API调用,终端说const api2中的id =等待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;
FileModel.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给我有关重构上下文的投入!干杯!
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句