Lo logré! Creé mi propio Router, con link y la posibilidad de usar HashRouter.
Al momento de comentar, no hay ninguna solución en los comentarios. Los invito a que prueben el reto! Y si ya lo hicieron, a que lo compartan.
Fue un muy buen reto. Casi me rindo muchas veces, pero finalmente lo terminé. Dejo mi solución.
Router.jsx
import { useState } from 'react'
import { PathContext } from './Context'
export function Router({ children }) {
const [currentPath, setCurrentPath] = useState(window.location.pathname)
const routes = []
const navigate = to => {
window.history.pushState({}, '', to)
setCurrentPath(to)
}
return (
<PathContext.Provider
value={{ currentPath, setCurrentPath, routes, navigate }}
>
{children}
</PathContext.Provider>
)
}
Route.jsx
import { useContext } from 'react'
import { PathContext } from './Context'
export function Route({ path, element }) {
const { currentPath, routes } = useContext(PathContext)
//Push all routes except '*' (not found) to routes[]
const routeInRoutes = routes.includes(path)
if (!routeInRoutes && path != '*') routes.push(path)
//returning in match
if (currentPath == path) return element
// Not found case
const currentPathInRoutes = routes.includes(currentPath)
if (path == '*' && !currentPathInRoutes) return element
}
Link.jsx
import { useContext } from 'react'
import { PathContext } from './Context'
const styles = {
textDecoration: 'underline',
color: 'blue',
cursor: 'pointer',
}
export function Link({ to, children }) {
const { navigate } = useContext(PathContext)
return (
<a style={styles} onClick={() => navigate(to)}>
{children}
</a>
)
}
HashRouter.jsx
import { useState } from 'react'
import { PathContext } from './Context'
export function HashRouter({ children }) {
const windowPath = window.location.pathname.replace(/^\/#/, '')
const [currentPath, setCurrentPath] = useState(windowPath)
const routes = []
const navigate = to => {
window.history.pushState({}, '', `/#${to}`)
setCurrentPath(to)
}
return (
<PathContext.Provider
value={{ currentPath, setCurrentPath, routes, navigate }}
>
{children}
</PathContext.Provider>
)
}
Context.jsx
import { createContext } from 'react'
export const PathContext = createContext()
App.jsx
import { Link } from '../router/Link'
import { Route } from '../router/Route'
import { Router } from '../router/Router'
export function App() {
return (
<Router>
<Route element={<HomePage />} path="/" />
<Route element={<BlogPage />} path="/blog" />
<Route element={<NotFound />} path="*" />
</Router>
)
}
function HomePage() {
return (
<>
<h1>You are in the home</h1>
<Link to="/blog">Go to blog</Link>
<p></p>
<Link to="/random-link">Go to non-existent page</Link>
</>
)
}
function BlogPage() {
return (
<>
<h1>You are in the blog</h1>
<Link to="/">Back to home</Link>
</>
)
}
function NotFound() {
return (
<>
<h1>Page not found</h1>
<Link to="/">Go to home</Link>
</>
)
}
AppWithHash.jsx
import { Link } from '../router/Link'
import { Route } from '../router/Route'
import { HashRouter } from '../router/HashRouter'
export function AppWithHash() {
return (
<HashRouter>
<Route element={<HomePage />} path="/" />
<Route element={<BlogPage />} path="/blog" />
<Route element={<NotFound />} path="*" />
</HashRouter>
)
}
function HomePage() {
return (
<>
<h1>You are in the home</h1>
<Link to="/blog">Go to blog</Link>
<p></p>
<Link to="/random-link">Go to non-existent page</Link>
</>
)
}
function BlogPage() {
return (
<>
<h1>You are in the blog</h1>
<Link to="/">Back to home</Link>
</>
)
}
function NotFound() {
return (
<>
<h1>Page not found</h1>
<Link to="/">Go to home</Link>
</>
)
}
Todo se ve tan fácil y obvio una vez terminado jajaja… para nada se sintió así. Como siempre, tuve que volver a revisar todo mi conocimiento, consultar muchas fuentes y probar mil cosas.
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?