При нажатии на изображение следует перейти к компоненту

Фон

У меня возникла проблема с реализацией маршрутов реагирования

Всем здравствуйте. Простите, но я здесь впервые и уже писал об этом на Codecademy. Я собираюсь скопировать и вставить свою ветку, которую я создал на Codecademy, потому что я думаю, что там я довольно хорошо изложил проблему:

Всем привет. Я выполнял один из открытых проектов в программе курса Front End Engineer, связанный с созданием собственного приложения React с нуля и публикацией его на github и netlify. Мне нравятся эти открытые проекты, потому что они предоставляют большую творческую свободу. В любом случае, сейчас я очень близок к созданию своего самого первого веб-сайта. Он называется Музей видеоигр. Это всего лишь довольно простой список из 10 моих любимых видеоигр, где у каждой видеоигры есть собственная страница с небольшим мини-обзором и информацией о том, где купить игры, если люди захотят их опробовать.

Я также продолжал учебу во время работы над проектом и узнал о React Router и всех его различных компонентах. В любом случае, сейчас я столкнулся с проблемой: я импортировал все отдельные страницы (каждая из которых названа в честь соответствующей видеоигры с именем расширения файла .js) и обернул основной раздел возврата приложения () с помощью <BrowserRouter> ...</BrowserRouter>

Предполагаемая функциональность этого состоит в том, чтобы сделать фотографии различных видеоигр интерактивными и перенести их на страницу, которую я написал для каждой видеоигры (все со своими собственными функциями JS, которые я импортировал в App.js).

Надеюсь, я достаточно ясно выразился. Пожалуйста, дайте мне знать, если вам нужно, чтобы я объяснил дальше.

Проблема

Итак, я хочу, чтобы каждое изображение игры было кликабельным, и чтобы щелчок отправлял меня к соответствующей функции .js каждой игры, но сейчас это не так. Я не уверен, почему эти ссылки не выполняют намеченные функции.

Я импортировал все необходимые функции React в файлы App.js, index.js и .js для каждой созданной мной страницы игры. Я чувствую себя так близко к достижению запланированного результата, которого пытался достичь на прошлой неделе или около того, но мне нужно немного больше руководства.

Вот код:


 /*Free Javascript Code for the VideoGame Museum Project
    Copyright (C) 2024  Elias L. Turner

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.*/
import React from 'react';
import ReactDOM from 'react-dom/client';
import { RouterProvider, createBrowserRouter, BrowserRouter, createRoutesFromElements, Route, Outlet, Link, NavLink } from 'react-router-dom'
import PN03 from './PN03'
import Minetest from './Minetest'
import RedOrchestra from './RedOrchestra'
import EuroTruckSim2 from './EuroTruckSim2'
import RallyChallenge2000 from './RallyChallenge2000'
import MirrorsEdge from './MirrorsEdge'
import MidwayArcadeTreasures3 from './MidwayArcadeTreasures3'
import JetSetRadio from './JetSetRadio'
import GauntletDarkLegacy from './GauntletDarkLegacy'
import Openarena from './Openarena'
import logo from './videogame museum website project logo.png';
import './App.css';
import pn03 from './pn03 gamecube box art front.jpg'
import openarena from './open arena screenshot.jpg'
import minetest from './minetest logo.jpg'
import redorchestra from './red orchestra ostfront.jpeg'
import rallychallenge2000 from './Rally Challenge 2000 box art.jpg'
import mirrorsedge from './Mirror_s_Edge box art.jpg'
import jetsetradio from './Jet Set Radio Dreamcast front cover.jpg'
import eurotrucksim2 from './Euro Truck Simulator 2 cover.jpg'
import midwayarcadetreasures from './Midway Arcade Treasures 3 box art front.jpg'
import gauntletdarklegacy from './gauntlet dark legacy front box art.jpg'



const appRouter = createBrowserRouter(createRoutesFromElements(<Route path = "/" element = { <MainContent/> }>
                                   <Route path = "PN03" element = { <PN03/> } />
                                   <Route path = "Minetest" element = { <Minetest/> } />
                                   <Route path = "RedOrchestra" element = { <RedOrchestra/> } />
                                   <Route path = "EuroTruckSim2" element = { <EuroTruckSim2/> } />
                                   <Route path = "RallyChallenge2000" element = { <RallyChallenge2000/> } />

                                   <Route path = "MirrorsEdge" element = { <MirrorsEdge/> } />
                                   <Route path = "MidwayArcadeTreasures3" element = { <MidwayArcadeTreasures3/> } />
                                   <Route path = "JetSetRadio" element = { <JetSetRadio/> } />
                                   <Route path = "GauntletDarkLegacy" element = { <GauntletDarkLegacy/> } />
                                   <Route path = "Openarena" element = { <Openarena/> } />
                              
                                   </Route>
                                  ));



function MainContent() {

    
    const navigation = (<div><img src = {logo} height = "200" /><nav>Welcome to The Video Game Museum, a list of my own personal hall of fame of video games</nav>
            <span><a href = "">Home </a> <a href = "catalog.html">Catalog </a><a href = "aboutme.html"> About Me</a></span> </div>)
    const sidebar = (<h5>This is the content for the RSS feed</h5>)
    const footer = (<footer>The content of this website is property of its respective owners. No copyright infringement intended.</footer>)
    const images = {
    border: "2px solid lightblue",
    display: "flex",
    flexWrap: "wrap",
    justifyContent: "space-around",
    padding: "10px 10px 10px 10px",
    height: "650px",
    position: "relative",
    }
    
    

    return (
    <BrowserRouter>
<div className = "MainContent">
        <div className = "Navigation">{navigation}</div>
        <h1>Welcome to Elias L. Turner's VideoGame Museum</h1>
        <p>
         My name is Elias, and I have been a gamer since I was 5 years old.
<br /><br />
My first video game console was the Nintendo Game Boy Color. It was a see through purple system and the first couple of games I got with the system included Kirby Tilt n Tumble, Megaman Xtreme, and Formula 1. It really helped me pass the time in my childhood, considering that I was homeschooled and had a lot of free time on my hands despite my parents' best efforts.
        <br />
        <br />

    I made this website as a tribute to some of my favorite games that I\'ve played in my 28 years on this bizarre planet. You will notice that most of the games are not super new or high-tech--This is because I don\'t place undue emphasis on graphics and gimmicks unlike a lot of modern gamers. I also don\'t have much time to play modern games these days considering that I work two jobs, so I can\'t comment on some of the great games that I\'m sure have been released recently. All I know is that this list of games are some that were the most influential to me in my upbringing (being babysat by my video game consoles).

Below is a list of my top 10 favorite videogames of all time. I hope you enjoy checking out this top 10 countdown. <br /> <br /> Thank you and have a lovely day.
        </p>
        <div id = "sidebar">{sidebar}</div>
<div id = "Images" style = {images}>
    <Link to = {PN03}><img src = {pn03} height = "200" border = "2px 2px solid lightblue"/>{PN03}</Link>
<Link to = {Openarena}><img src = {openarena} height = "150" border = "2px 2px solid lightblue" />{Openarena}</Link>
<Link to = {Minetest}><img src = {minetest} height = "150" border = "2px 2px solid lightblue" />{Minetest}</Link>
<Link to = {RedOrchestra}><img src = {redorchestra} height = "200" border = "2px 2px solid lightblue"/>{RedOrchestra}</Link>
<Link to = {RallyChallenge2000}><img src = {rallychallenge2000} height = "175" border = "2px 2px solid lightblue" />{RallyChallenge2000}</Link>
<Link to = {MirrorsEdge}><img src = {mirrorsedge} height = "200" border = "2px 2px solid lightblue" />{MirrorsEdge}</Link>
<Link to = {JetSetRadio}><img src = {jetsetradio} height = "200" border = "2px 2px solid lightblue"/>{JetSetRadio}</Link>
<Link to = {EuroTruckSim2}><img src = {eurotrucksim2} height = "150" border = "2px 2px solid lightblue"/>{EuroTruckSim2}</Link>
<Link to = {MidwayArcadeTreasures3}><img src = {midwayarcadetreasures} height = "200" border = "2px 2px solid lightblue" />{MidwayArcadeTreasures3}</Link>
<Link to = {GauntletDarkLegacy}><img src = {gauntletdarklegacy} height = "200" border = "2px 2px solid lightblue" />{GauntletDarkLegacy}</Link> </div>
       
        <footer>{footer}</footer>
 <a
          className = "App-link"
          href = "https://reactjs.org"
          target = "_blank"
          rel = "noopener noreferrer"
        >
          Learn ReactJS
        </a>
    </div>
    </BrowserRouter>

  );
    

}

export default MainContent;

Вот фотография того, как выглядит мой сайт (сверху главной страницы). Это все еще нуждается в некоторых завершающих штрихах, но я хочу, чтобы эти изображения загружали свои собственные функции js, которые я импортировал в файл app.js, когда я нажимаю на них (фото прикреплено к моему сообщению)

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
0
73
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

вы передаете компонент профессионалам «to» в Link.its принимает строковое значение. можешь пожалуйста попробовать, как показано ниже <Link to = {'/GauntletDarkLegacy'}><img src = {gauntletdarklegacy} height = "200" border = "2px 2px solid lightblue" />{GauntletDarkLegacy}</Link> </div> `

Ответ принят как подходящий

Проблемы

  • Вы неправильно передаете ссылку на импортированные компоненты React в качестве реквизита to компонента Link. Link ожидает объект To или строковое значение. Целевые пути должны соответствовать тем, которые вы определили в своих маршрутах.
  • Символы Link отображают изображение и ссылку на компонент, на который вы хотите создать ссылку. Компоненты отображаются маршрутизатором и маршрутами.
  • MainContent отображает посторонний BrowserRouter, это инвариантная ошибка для вложенных маршрутизаторов.
  • Компонент маршрута макета MainContent должен отображать Outlet там, где он хочет отображать вложенные маршруты.

Решение

  • Link целевые пути должны соответствовать отображаемым маршрутам.
  • Удалите ссылку на компонент в ссылках.
  • Удалите вложенные BrowserRouter.
  • Компонент рендеринга Outlet.
import React from 'react';
import ReactDOM from 'react-dom/client';
import {
  RouterProvider,
  createBrowserRouter,
  createRoutesFromElements,
  Route,
  Outlet,
  Link,
  NavLink
} from 'react-router-dom';
import PN03 from './PN03';
import Minetest from './Minetest';
import RedOrchestra from './RedOrchestra';
import EuroTruckSim2 from './EuroTruckSim2';
import RallyChallenge2000 from './RallyChallenge2000';
import MirrorsEdge from './MirrorsEdge';
import MidwayArcadeTreasures3 from './MidwayArcadeTreasures3';
import JetSetRadio from './JetSetRadio';
import GauntletDarkLegacy from './GauntletDarkLegacy';
import Openarena from './Openarena';
import logo from './videogame museum website project logo.png';
import './App.css';
import pn03 from './pn03 gamecube box art front.jpg'
import openarena from './open arena screenshot.jpg'
import minetest from './minetest logo.jpg'
import redorchestra from './red orchestra ostfront.jpeg'
import rallychallenge2000 from './Rally Challenge 2000 box art.jpg'
import mirrorsedge from './Mirror_s_Edge box art.jpg'
import jetsetradio from './Jet Set Radio Dreamcast front cover.jpg'
import eurotrucksim2 from './Euro Truck Simulator 2 cover.jpg'
import midwayarcadetreasures from './Midway Arcade Treasures 3 box art front.jpg'
import gauntletdarklegacy from './gauntlet dark legacy front box art.jpg'

Создайте маршрутизатор:

const appRouter = createBrowserRouter(
  createRoutesFromElements(
    <Route path = "/" element = {<MainContent />}>
      <Route path = "PN03" element = {<PN03 />} />
      <Route path = "Minetest" element = {<Minetest />} />
      <Route path = "RedOrchestra" element = {<RedOrchestra />} />
      <Route path = "EuroTruckSim2" element = {<EuroTruckSim2 />} />
      <Route path = "RallyChallenge2000" element = {<RallyChallenge2000 />} />
      <Route path = "MirrorsEdge" element = {<MirrorsEdge /> } />
      <Route path = "MidwayArcadeTreasures3" element = {<MidwayArcadeTreasures3 />} />
      <Route path = "JetSetRadio" element = {<JetSetRadio />} />
      <Route path = "GauntletDarkLegacy" element = {<GauntletDarkLegacy />} />
      <Route path = "Openarena" element = {<Openarena />} />
    </Route>
  )
);

Создайте компонент маршрута макета MainContent:

function MainContent() {
  const navigation = <div>...</div>;
  const sidebar = <h5>...</h5>;
  const footer = <footer>....</footer>;
  const images = { ... };

  return (
    <div className = "MainContent">
      <div className = "Navigation">{navigation}</div>
      <h1>Welcome to Elias L. Turner's VideoGame Museum</h1>
      <p>
        ....
      </p>
      <div id = "sidebar">{sidebar}</div>

      <div id = "Images" style = {images}>
        <Link to = "PN03">
          <img src = {pn03} height = "200" border = "2px 2px solid lightblue" />
        </Link>
        <Link to = "Openarena">
          <img src = {openarena} height = "150" border = "2px 2px solid lightblue" />
        </Link>
        <Link to = "Minetest">
          <img src = {minetest} height = "150" border = "2px 2px solid lightblue" />
        </Link>
        <Link to = "RedOrchestra">
          <img src = {redorchestra} height = "200" border = "2px 2px solid lightblue"/>
        </Link>
        <Link to = "RallyChallenge2000">
          <img src = {rallychallenge2000} height = "175" border = "2px 2px solid lightblue" />
        </Link>
        <Link to = "MirrorsEdge">
          <img src = {mirrorsedge} height = "200" border = "2px 2px solid lightblue" />
        </Link>
        <Link to = "JetSetRadio">
          <img src = {jetsetradio} height = "200" border = "2px 2px solid lightblue"/>
        </Link>
        <Link to = "EuroTruckSim2">
          <img src = {eurotrucksim2} height = "150" border = "2px 2px solid lightblue"/>
        </Link>
        <Link to = "MidwayArcadeTreasures3">
          <img src = {midwayarcadetreasures} height = "200" border = "2px 2px solid lightblue" />
        </Link>
        <Link to = "GauntletDarkLegacy">
          <img src = {gauntletdarklegacy} height = "200" border = "2px 2px solid lightblue" />
        </Link>
      </div>

      <Outlet /> {/* nested routes render here */}
       
      <footer>{footer}</footer>
      <a
        className = "App-link"
        href = "https://reactjs.org"
        target = "_blank"
        rel = "noopener noreferrer"
      >
        Learn ReactJS
      </a>
    </div>
  );
}

Создайте и экспортируйте компонент, который отображает RouterProvider и маршрутизатор приложения:

const MainApp = () => <RouterProvider router = {appRouter} />;

export default MainApp;

Привет, Дрю. Я очень ценю ваш ответ. Это мне очень помогло. Теперь, когда я нажимаю на ссылки, он показывает имена URL-адресов, которые он должен отображать, но не отображает фактическое содержимое. Я думаю, судя по тому, что вы говорите, я довольно близок к тому, чтобы исправить это. У меня есть только один вопрос, который мне действительно нужно задать. В последней части, где вы сказали создать и визуализировать компонент, который отображает RouterProvider и маршрутизатор приложения... Вы имеете в виду сделать это в новом, только что созданном файле .js, верно? или это также входит в тело app.js?

Emandudeguy 05.04.2024 12:51

@Emandudeguy Основываясь на предоставленном вами коде, я предположил, что вы экспортируете MainContent по умолчанию и визуализируете его непосредственно в индексном файле, например. root.render(<MainContent />. В изменениях, которые я предложил выше, MainContent теперь является корневым компонентом маршрута макета, т. е. отображается с помощью appRouter, и поэтому теперь вам нужно будет экспортировать компонент, который отображает RouterProvider (который передается appRouter) для отображения в индексе. файл, например root.render(<MainApp />). Я не стал называть его App, чтобы избежать путаницы, но, возможно, это только еще больше запутало его, извините. Надеюсь, теперь это имеет смысл.

Drew Reese 06.04.2024 01:02

Правильно, я отображаю MainContent в индексе JS. Но вы меня потеряли... Вы говорите, что компонент appRouter нужно визуализировать внутри другого компонента, а затем передать в индекс JS? и если да, то где? выше или ниже компонента <MainContent />?

Emandudeguy 06.04.2024 08:44

Кроме того, чтобы внести ясность, MainContent (блок кода, над которым мы работали в этой теме) отображается в App.js. Различные веб-страницы созданного мной сайта отображаются как отдельный компонент React, или, по крайней мере, я это пытаюсь сделать.

Emandudeguy 06.04.2024 08:46

@Emandudeguy Видите ли вы в моем ответе последний фрагмент кода из исходного кода, MainApp, который экспортируется по умолчанию? Это компонент, который вы экспортируете для визуализации маршрутизатора. MainContent отображается маршрутизатором над ним в том же файле и не экспортируется. Другими словами, этот новый MainApp экспорт заменил ваш старый MainContent экспорт.

Drew Reese 06.04.2024 08:46

То есть это выходит за рамки компонента MainContent? совершенно вне этого, вообще не связан с ним, верно?

Emandudeguy 06.04.2024 08:53

А еще меня очень смущает <Outlet/> // render nested routers here

Emandudeguy 06.04.2024 08:55

@Emandudeguy Да, MainApp снаружи MainContant. MainApp отображает маршрутизатор, который отображает MainContent. MainContent необходимо отобразить Outlet для вложенных Route компонентов, которые он обертывает.

Drew Reese 06.04.2024 08:56

Давайте продолжим обсуждение в чате.

Emandudeguy 06.04.2024 08:56

Другие вопросы по теме