Я боролся со своим первым сольным проектом из-за отсутствия опыта, вот какая у меня проблема:
Мне нужно установить компонент Link (из react-router-dom), который переводит меня на другую новую страницу, когда я нажимаю кнопку. Думал, что при выборе мне нужно передать ссылку (и контекст) идентификатор, чтобы я мог получить данные из 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;
Пока это файл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: Может быть, вы сможете найти некоторые вещи для рефакторинга (позже мне нужно будет проверить мой код). Если вы найдете что-то подобное, любая помощь будет оценена по достоинству!
ОБНОВЛЕНИЕ
По рекомендации Линды я объединил два контекста в один и изменил некоторые строки кода, который я написал ранее, я не могу установить состояние для передачи одиночной модели компоненту fileModel, а ссылка все еще не работает, я думал в функциях что это можно сделать, я сделал другое состояние, одиночное modelo, но когда я нажимаю кнопку, я получаю ошибку и undefined, потому что Idk, как установить в состоянии Id и, таким образом, передать его вызову API, терминал говорит, что идентификатор в константе api2 = ожидание выборки (https://challenge.agenciaego.tech/models/${id}
); не определено.
Router
внутриModel
. Кроме того, я не совсем уверен, на что похожа навигация. Похоже, вы пытаетесь использовать один и тот же компонент как для миниатюры модели, так и для страницы одной модели. Вы не хотите этого. Вы можете делиться многократно используемыми частями, но вы хотите, чтобы их обертывали разными компонентами. - person Linda Paiste   schedule 06.02.2021