No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Reto: crea tu propio React Router

29/30
Recursos

Aportes 5

Preguntas 0

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

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.

despes de todos estos retos de este buen curso he decidido aceptar un reto: hacer el curso de react router DOM5

Lo consegui鈥 entre pasadas y venidas en resumen un masomenos.

Implemente:
1)HashRouter: Encargado de agregar el hash en los paths

import React, { useEffect } from 'react'
const location = window.location

const HashRouter = ({children}) => {    
  let containsHashRoute = location.hash
    useEffect(()=>{
       if(containsHashRoute){
        location.href = location.origin + `/${location.hash}`
       }else{
        location.href = location.origin + '/#/'
       }
    },[])

  return (
    <>
        {children}
    </>
  )
}

export default HashRouter

2)Route: Encargado solo de crear una ruta. o el path

import React from 'react'

let routes = []
const Route = ({children,path}) => {
  routes.push(path)

  let route = routes.find((route,i )=> route === path)
  //console.log(route)
  if(route){
    return (
      <>
          {children}
      </>
    )
  }
}

export default Route

3)Switch: Encargado de renderizar solo el componente cuando el path coincida

import React from 'react'

let location = window.location

let formaterPath = (path) => path = path[0] + '#' + path


const Switch = ({children}) => {
    let locationHash = location.hash

    let childrensFind = children.find(children =>{
        let path = formaterPath(children.props.path)

        if(path.includes('*')){
            return children
        }

        if(locationHash.includes('/edit/')){
            locationHash = '#/edit/:id'
        }

        if(path.includes(locationHash)){
            //console.log('Mostar',children.props.path)
            return children
        }
    })

    if(childrensFind){
      return(
        <>
            {childrensFind.props.children}
        </>
      )
    }
}

export default Switch
  1. Hook useHistory o useNavigation. Encargado de recargar la pagina dependiendo del path que reciba, (Aqui hago una aclaracion porque me cambia el path pero no me renderiza el componente, no logre resolver este eror)
function useHistory(path){
    return function(path){
        setTimeout(()=>{
            window.location.assign(path)
        })
    }
}

export {useHistory}

5)useParams encargado de obtener el parametro que pasemos

let location = window.location

function useParams(){
    let formatParamIndex = location.hash.lastIndexOf('/') + 1
    let param = location.hash.slice(formatParamIndex)
    
    return{
        params : {
            param
        }
    }
}

export {useParams}

De esta forma ya puedes crear un ruteo basico con un hash y dependiendo de la ruta renderizar un componente o no, obtener parametros de una ruta y dependiendo de un evento o no navegar a tal path.

Todo esto gracias al objeto location de javascript vanilla

Hola todos! Resultado del reto. Cualquier feedback es bienvenido.
Link del repositorio: https://github.com/jp-cortes/navigation-react

Link del repo utilizando el router creado por mi implementando el proyecto del curso

https://github.com/TheJB4/react-router-by-thejb29