You don't have access to this class

Keep learning! Join and start boosting your career

Aprovecha el precio especial y haz tu profesión a prueba de IA

Antes: $249

Currency
$209
Suscríbete

Termina en:

0 Días
2 Hrs
27 Min
21 Seg

Creando las rutas de TODO Machine

19/30
Resources

How to organize a React project with routes?

Welcome to the world of React Routing. A key component in building modern applications with React is how to organize our files and structure our folders to effectively handle multiple views or routes. In this analysis, we'll break down how to structure a project with React Router DOM and share helpful tips for you to apply this methodology in your own work.

What is React Router DOM and why is it relevant?

React Router DOM is an essential library for handling navigation in React applications. It allows you to define multiple routes in a single application, improving its fluidity and modularity.

  • Modularity: Helps to split the code, assigning specific components to different views.
  • Maintainability: Makes it easy to update or change path configurations without completely affecting the application logic.
  • Convenience: Optimizes the developer experience by handling URL states, which is crucial for more complex web applications.

How to organize the folder and file structure?

A good strategy starts by organizing and dividing your project into key folders. Let's break down an example of how you might organize your React project:

Creating specific folders: UI and Routes.

  1. UI folder:

    • Stores components that are reused across multiple views.
    • Provides a central place for generic UI components.
  2. Routes folder:

    • Stores view-specific components.
    • Allows for the coexistence of path-specific components along with shared components.

Ideal structure

  • src
    • UI
      • ComponentA.jsx
      • ComponentB.jsx
      • [...]
    • Routes
      • Home
        • HomePage.jsx
      • NewTodo
        • NewAllPage.jsx
      • EditTodo
        • EditAllPage.jsx

How to implement and configure React Router in the project?

Implementing React Router requires configuring a number of routes in your App component. We will use HashRouter to handle the routes in our project.

import React from 'react';import { HashRouter as Router, Route, Switch } from 'react-router-dom';import HomePage from './Routes/Home/HomePage';import EditTodoPage from './Routes/Edit/EditTodoPage';import NewTodoPage from './Routes/New/NewTodoPage';
function App() { return ( <Router> <Switch> {/* Route Home*/} <Route exact  path="/"  component={HomePage}/> {/* Route NewTask*/} <Route  path="/new"  component={NewTodoPage}/> {/* Route Edit Task with Dynamic Parameter*/} <Route  path="/edit/:id"  component={EditTodoPage}/> {/* Handling not found routes*/} <Route  path="*"  render={() => <p>Not  found</p>}/> </Switch> </Router> );}
export default App;

How to manage components when modifying structures?

  1. Automatic imports: When moving files, some development environments such as Visual Studio Code can automatically adjust import paths.

  2. Use of aliases: Consider using aliases for imports, which will make it easier to manage complex and repetitive references in your files.

  3. Dynamic path handling: Use patterns in paths to support paths that require parameters, such as IDs, allowing specific components for actions such as editing a To Do.

What's next after configuring the paths?

With this base structure and configuration, it is crucial to maintain an iterative approach. As your application grows, take advantage of React Router DOM capabilities to:

  • Introduce authentication features, protecting certain routes.
  • Handle specific states and hooks for history management and navigation.
  • Optimize loading through lazy loading to improve page performance.

Stay motivated and keep innovating in the organization of your applications, this not only improves the user experience, but also yours as a developer. What is the structure that has worked best for you? Share your experiences in the comments!

Contributions 20

Questions 6

Sort by:

Want to see more contributions, questions and answers from the community?

Sienndo creativos, asi quedo mi notFound

Como mi TODOs machine lo hice con la temática de Naruto, hice un simple not found component, solamente con una imagen y un título. así quedó.

Yo soy revelde y no le hice caso a la junta Directiva y estoy trabajando en react 18 jejejejje muy bueno el reto

Esta es la estructura que yo uso. Me parece bastante cómoda.

Para los que quieran usar Alias para hacer imports más limpios y evitar usar Paths extensos y relativos . Tienen que configurar su herramienta build tool.
.
En mi caso uso Vite.js entonces lo modifique de la siguiente manera

vite.config.js

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  resolve: {
    alias: {
      '@App': '/src/App',
      '@components': '/src/components',
      '@hooks': '/src/hooks',
      '@pages': '/src/pages',
      // Add more aliases as needed
    }
  }
})

Tambien hice un archivo en el Root del projecto llamado jsconfig.json para ayudarle a VSCode a reconocer estos aliases y poder seguir usando auto-imports e IntelliSense.

jsconfig.json

{
  "compilerOptions": {
    "baseUrl": "./",
    "paths": {
      "@App/*": ["src/App/*"],
      "@components/*": ["src/components/*"],
      "@hooks/*": ["src/hooks/*"],
      "@pages/*": ["src/pages/*"],
      // Add more aliases as needed
    }
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}

.
Una vez hecho esto ya podemos actualizar nuestros imports.

//import sin path Aliases
import SomeComponent from '../../components/SomeComponent';

//import con path aliases
import SomeComponent from '@components/SomeComponent';

Yo siempre uso alias. Me facilita mucho el trabajo.

Siempre me a gustado mucho esta estructura, carpetas para hooks, componentes y paginas.

mi organización:

Creando las rutas de TODO Machine

.
Vamos a reestructurar el proyecto de TodoMachine para remplazar portales y modales, por rutas utilizando React Router DOM.
.
La estructura de carpetas será la siguiente.
.

public
src
- routes
- ui
- index.css
- index.js
.gitignore
README.md
package-lock.json
package.json
yarn.lock

.
Dentro de src se va a dar el mayor cambio, puesto que ahora manejamos un archivo de routes que contiene nuestras rutas, nuestros custom hooks y la aplicación principal en App.js.
.

routes
- edit
-- EditTodoPage.js
- home
-- HomePage.js
- new
-- NewTodoPage.js
- App.css
- App.js
- useLocalStorage.js
- useTodos.js

.
Cada ruta tiene su propia página o componente que se va a renderizar para esa ruta.
.

import React from 'react';

function EditTodoPage() {
  return (
    <p>Editar TODO</p>
  );
}

export { EditTodoPage };
import React from 'react';
import { useTodos } from '../useTodos';
import { TodoHeader } from '../../ui/TodoHeader';
import { TodoCounter } from '../../ui/TodoCounter';
import { TodoSearch } from '../../ui/TodoSearch';
import { TodoList } from '../../ui/TodoList';
import { TodoItem } from '../../ui/TodoItem';
import { TodosError } from '../../ui/TodosError';
import { TodosLoading } from '../../ui/TodosLoading';
import { EmptyTodos } from '../../ui/EmptyTodos';
import { TodoForm } from '../../ui/TodoForm';
import { CreateTodoButton } from '../../ui/CreateTodoButton';
import { Modal } from '../../ui/Modal';
import { ChangeAlert } from '../../ui/ChangeAlert';

function HomePage() {
  const { state, stateUpdaters } = useTodos();

  const {
    error,
    loading,
    searchedTodos,
    totalTodos,
    completedTodos,
    openModal,
    searchValue,
  } = state;

  const {
    setOpenModal,
    addTodo,
    completeTodo,
    deleteTodo,
    setSearchValue,
    sincronizeTodos,
  } = stateUpdaters;
  
  return (
    <React.Fragment>
      <TodoHeader loading={loading}>
        <TodoCounter
          totalTodos={totalTodos}
          completedTodos={completedTodos}
        />
        <TodoSearch
          searchValue={searchValue}
          setSearchValue={setSearchValue}
        />
      </TodoHeader>

      <TodoList
        error={error}
        loading={loading}
        totalTodos={totalTodos}
        searchedTodos={searchedTodos}
        searchText={searchValue}
        onError={() => <TodosError />}
        onLoading={() => <TodosLoading />}
        onEmptyTodos={() => <EmptyTodos />}
        onEmptySearchResults={
          (searchText) => <p>No hay resultados para {searchText}</p>
        }
      >
        {todo => (
          <TodoItem
            key={todo.text}
            text={todo.text}
            completed={todo.completed}
            onComplete={() => completeTodo(todo.text)}
            onDelete={() => deleteTodo(todo.text)}
          />
        )}
      </TodoList>

      {!!openModal && (
        <Modal>
          <TodoForm
            addTodo={addTodo}
            setOpenModal={setOpenModal}
          />
        </Modal>
      )}

      <CreateTodoButton
        setOpenModal={setOpenModal}
      />

      <ChangeAlert
        sincronize={sincronizeTodos}
      />
    </React.Fragment>
  );
}

export { HomePage };
import React from 'react';

function NewTodoPage() {
  return (
    <p>New Todo</p>
  );
}

export { NewTodoPage };

.
Es evidente que las importaciones van a cambiar, debido a que todos nuestros componentes de interfaz se movieron a una carpeta llamada ui, entre otros cambios.
.
La estructura de la carpeta ui contempla lo siguiente.
.

ui
- ChangeAlert
- CreateTodoButton
- EmptyTodos
- Modal
- TodoCounter
- TodoForm
- TodoHeader
- TodoIcon
- TodoItem
- TodoList
- TodoSearch
- TodosError
- TodosLoading

.
A todo esto, los 2 archivos más importantes para poder migrar la aplicación a rutas serán index.js dentro de src, y App.js que se encuentra dentro de routes.
.

import React from 'react';
import ReactDOM from 'react-dom';
import { App } from './routes/App';
import './index.css';

ReactDOM.render(
  <App />,
  document.getElementById('root')
);
import React from 'react';
import { HashRouter, Route, Routes } from 'react-router-dom';
import { EditTodoPage } from './edit/EditTodoPage';
import { HomePage } from './home/HomePage';
import { NewTodoPage } from './new/NewTodoPage';

function App() {
  return (
    <HashRouter>
      <Routes>
        <Route path="/" element={<HomePage />} />
        <Route path="/new" element={<NewTodoPage />} />
        <Route path="/edit/:id" element={<EditTodoPage />} />
        <Route path="*" element={<p>Not Found</p>} />
      </Routes>
    </HashRouter>
  );
}

export { App };

.
En App.js creamos la estructura principal de rutas utilizando a HashRouter como provider con 4 rutas principales que ya hemos mencionado previamente, añadiendo una ruta adicional para rutas que sean Not Found.
.
Finalmente lo exportamos como un export nombrado, por lo que lo importamos de la manera correspondiente desde el index.js que se encuentra en src.

Te dan puntos por esto, verdad?

bueno algo sencillo decidi crear un componente y su respectivo css

import React from "react";
import "./notfound.css"; // Importa los estilos CSS

const NotFound = () => {
    return (
        <div className="container">
            <h1 className="heading">¡Oops, Te Perdiste!</h1> 
            <p>Esta página es tan escurridiza como un unicornio en patines.</p>
            <img
                className="image" 
                src="https://img.freepik.com/vector-gratis/lindo-unicornio-jugando-patinaje-sobre-ruedas-ilustracion_138676-3287.jpg?w=740&t=st=1691293684~exp=1691294284~hmac=b7bffe0c0e9c8be85358879314e1199cbaebdc0378cbaff6d8460804b88d8163"
                alt="Lost Unicorn"
            />
        </div>
    );
};

export {NotFound} ;

css

.container {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100vh;
    font-family: sans-serif;
}

.heading {
    font-size: 2rem;
    margin-bottom: 1rem;
}

.image {
    max-width: 50%; 
    height: auto;
}

En mi estructura tengo una carpeta llamada “Pages” y una llamada “Components”. Creo que tienen nombres bastantes descriptivos jajaja.
.
En mi caso, el componente App lo he introducido como cualquier otro componente dentro de la carpeta “Components” y tengo una carpeta de “Hooks” donde están los hooks ya creados y si se necesitan nuevos hooks también irán ahí

Como yo uso SASS tengo todos los estilos aparte

En mi caso suelo utilizar el NewPage también en el edit, solo que controlo si la ruta tiene algún id con el cual pueda buscar en la base de datos, en el caso de que exista el botón pasa de new a update y se cargan los datos en los campos.

Voy con React@18 y Material UI

Se me habia roto todo, puesto que lo hice levemente diferente al profe y fue un cacho, pero lo logré 😁🎉🎉🎉 ![](https://static.platzi.com/media/user_upload/upload-f44b843d-5d45-4be4-9b5f-0c18ec280791.png)
Holaa compaaas! les dejo para practicar inglés: **My english version branch:** <https://github.com/SebaMat3/react-todo/tree/feat/hashrouter-integration> **Branch name:** feat/hashrouter-integration **Commit message:** git commit -m "feat(router): implement HashRouter and reorganize directories for home & new/edit TODO flows \- Introduce HashRouter for navigation \- Add /new and /edit/:id routes \- Move related components into newly structured folders \- Remove modal approach in favor of page-based creation/editing"

Les dejo el código de mi App. Yo utilizo vite + typescript.
El tema del base y basename son configuraciones necesarias al subir a GitHub Pages y funcione correctamente pues no se trabaja en la ruta raiz.

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  base: '/todo_machine_ts/'
})

import { FC } from 'react'
import { BrowserRouter, Routes, Route } from 'react-router-dom'
import { Home } from './pages/Home'
import { NewTodo } from './pages/NewTodo'
import { EditTodo } from './pages/EditTodo'

const App: FC = () => {

  return (
    <BrowserRouter basename='todo_machine_ts'>
      <Routes>
        <Route path='/' element={<Home />} />
        <Route path='/new' element={<NewTodo />} />
        <Route path='/edit/:id' element={<EditTodo />} />
      </Routes>
    </BrowserRouter>
  )
}



export default App