├── .gitignore ├── .markdownlint.json ├── .nvmrc ├── .prettierrc ├── .vscode ├── extensions.json └── settings.json ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── app ├── Title.jsx ├── [post] │ ├── HighlightCode.css │ ├── Title.jsx │ └── page.jsx ├── api │ └── search │ │ └── route.ts ├── components │ ├── BookCover.tsx │ ├── ButtonRead.jsx │ ├── BuyBook.jsx │ ├── Card.jsx │ ├── Footer.jsx │ ├── Head.jsx │ ├── Header.jsx │ ├── ListOfQuestions.jsx │ ├── NextLogo.jsx │ ├── Pill.jsx │ ├── ReactLogo.jsx │ ├── SearchIcon.jsx │ ├── Stars.jsx │ ├── ThemeToggle.jsx │ └── Title.jsx ├── constants.js ├── globals.css ├── layout.jsx └── page.tsx ├── assets └── space-grotesk.bold.ttf ├── context └── ThemeContext.jsx ├── eslint.config.js ├── hooks └── useEventListener.ts ├── next.config.js ├── package.json ├── pnpm-lock.yaml ├── postcss.config.js ├── provider └── ThemeProvider.jsx ├── public ├── README.md ├── book.png ├── can-t-perform-a-react-state-update-on-an-unmounted-component.json ├── como-anadir-un-evento-a-un-componente-en-react.json ├── como-crear-un-componente-en-react.json ├── como-crear-un-hook-personalizado-custom-hook.json ├── como-funciona-el-hook-use-ref.json ├── como-mantener-los-componentes-puros-y-que-ventajas-tiene.json ├── como-podemos-ejecutar-codigo-cuando-el-componente-se-desmonta-del-arbol.json ├── como-podemos-ejecutar-codigo-cuando-el-componente-se-monta.json ├── como-puedes-abortar-una-peticion-fetch-con-use-effect-en-react.json ├── como-puedes-acceder-al-evento-nativo-del-navegador-en-react.json ├── como-puedes-aplicar-clases-css-a-un-componente-en-react-y-por-que-no-se-puede-usar-class.json ├── como-puedes-aplicar-estilos-en-linea-a-un-componente-en-react.json ├── como-puedes-cancelar-una-peticion-a-una-api-en-use-effect-correctamente.json ├── como-puedes-crear-un-server-side-rendering-con-react-desde-cero.json ├── como-puedes-escribir-comentarios-en-react.json ├── como-puedes-exportar-multiples-componentes-de-un-mismo-archivo.json ├── como-puedes-inicializar-un-proyecto-de-react-desde-cero.json ├── como-puedes-mejorar-el-rendimiento-del-server-side-rendering-en-react-para-evitar-que-bloquee-el-hilo-principal.json ├── como-puedes-prevenir-el-comportamiento-por-defecto-de-un-evento-en-react.json ├── como-puedes-registrar-un-evento-en-la-fase-de-captura-en-react.json ├── como-puedo-aplicar-estilos-de-forma-condicional-a-un-componente-en-react.json ├── como-puedo-importar-de-forma-dinamica-un-componente-en-react.json ├── como-puedo-inyectar-html-directamente-en-un-componente-de-react.json ├── como-puedo-pasar-un-parametro-a-una-funcion-que-maneja-un-evento-en-react.json ├── como-puedo-validar-el-tipo-de-mis-props.json ├── como-puedo-validar-las-propiedades-de-un-array-con-prop-types.json ├── como-puedo-validar-las-propiedades-de-un-objeto-con-prop-types.json ├── como-se-transforma-el-jsx.json ├── como-suscribirse-a-un-evento-en-use-effect.json ├── content │ ├── README.md │ ├── can-t-perform-a-react-state-update-on-an-unmounted-component.json │ ├── como-anadir-un-evento-a-un-componente-en-react.json │ ├── como-crear-un-componente-en-react.json │ ├── como-crear-un-hook-personalizado-custom-hook.json │ ├── como-funciona-el-hook-use-ref.json │ ├── como-mantener-los-componentes-puros-y-que-ventajas-tiene.json │ ├── como-podemos-ejecutar-codigo-cuando-el-componente-se-desmonta-del-arbol.json │ ├── como-podemos-ejecutar-codigo-cuando-el-componente-se-monta.json │ ├── como-puedes-abortar-una-peticion-fetch-con-use-effect-en-react.json │ ├── como-puedes-acceder-al-evento-nativo-del-navegador-en-react.json │ ├── como-puedes-aplicar-clases-css-a-un-componente-en-react-y-por-que-no-se-puede-usar-class.json │ ├── como-puedes-aplicar-estilos-en-linea-a-un-componente-en-react.json │ ├── como-puedes-cancelar-una-peticion-a-una-api-en-use-effect-correctamente.json │ ├── como-puedes-crear-un-server-side-rendering-con-react-desde-cero.json │ ├── como-puedes-escribir-comentarios-en-react.json │ ├── como-puedes-exportar-multiples-componentes-de-un-mismo-archivo.json │ ├── como-puedes-inicializar-un-proyecto-de-react-desde-cero.json │ ├── como-puedes-mejorar-el-rendimiento-del-server-side-rendering-en-react-para-evitar-que-bloquee-el-hilo-principal.json │ ├── como-puedes-prevenir-el-comportamiento-por-defecto-de-un-evento-en-react.json │ ├── como-puedes-registrar-un-evento-en-la-fase-de-captura-en-react.json │ ├── como-puedo-aplicar-estilos-de-forma-condicional-a-un-componente-en-react.json │ ├── como-puedo-importar-de-forma-dinamica-un-componente-en-react.json │ ├── como-puedo-inyectar-html-directamente-en-un-componente-de-react.json │ ├── como-puedo-pasar-un-parametro-a-una-funcion-que-maneja-un-evento-en-react.json │ ├── como-puedo-validar-el-tipo-de-mis-props.json │ ├── como-puedo-validar-las-propiedades-de-un-array-con-prop-types.json │ ├── como-puedo-validar-las-propiedades-de-un-objeto-con-prop-types.json │ ├── como-se-transforma-el-jsx.json │ ├── como-suscribirse-a-un-evento-en-use-effect.json │ ├── counter.json │ ├── cual-es-el-proposito-del-atributo-key-en-react-y-por-que-es-importante-usarlo-correctamente-al-renderizar-listas-de-elementos.json │ ├── cual-es-la-diferencia-entre-componente-y-elemento-en-react.json │ ├── cual-es-la-diferencia-entre-use-callback-y-use-memo.json │ ├── cuales-son-las-caracteristicas-principales-de-react.json │ ├── cuales-son-las-reglas-de-los-hooks-en-react.json │ ├── cuando-y-por-que-es-recomendable-importar-componentes-de-forma-dinamica.json │ ├── cuantos-use-effect-puede-tener-un-componente.json │ ├── es-buena-idea-usar-siempre-use-callback-para-optimizar-nuestros-componentes.json │ ├── es-buena-idea-usar-siempre-use-memo-para-optimizar-nuestros-componentes.json │ ├── es-react-una-biblioteca-o-un-framework-por-que.json │ ├── explica-casos-de-uso-del-hook-use-effect.json │ ├── index.json │ ├── moon.png │ ├── para-que-sirve-el-hook-use-callback.json │ ├── para-que-sirve-el-hook-use-deferred-value.json │ ├── para-que-sirve-el-hook-use-imperative-handle.json │ ├── para-que-sirve-el-hook-use-memo.json │ ├── para-que-sirve-el-metodo-clone-element-de-react.json │ ├── para-que-sirve-el-metodo-render-to-readable-stream.json │ ├── por-que-debemos-utilizar-una-funcion-para-actualizar-el-estado-de-react.json │ ├── por-que-es-recomendable-exportar-los-componentes-de-react-de-forma-nombrada.json │ ├── por-que-es-recomendable-usar-fragment-en-vez-de-un-div.json │ ├── por-que-no-podemos-usar-un-if-en-el-renderizado-de-un-componente.json │ ├── por-que-puede-ser-mala-idea-pasar-siempre-todas-las-props-de-un-objeto-a-un-componente.json │ ├── por-que-puede-ser-mala-practica-usar-el-index-como-key-en-un-listado-de-react.json │ ├── por-que-strict-mode-renderiza-dos-veces-la-aplicacion.json │ ├── puedes-poner-un-ejemplo-de-efectos-colaterales-en-react.json │ ├── que-diferencia-existe-entre-shadow-dom-y-virtual-dom.json │ ├── que-diferencia-hay-entre-componentes-controlados-y-no-controlados-que-ventajas-y-desventajas-tienen.json │ ├── que-diferencia-hay-entre-props-y-state.json │ ├── que-diferencia-hay-entre-render-to-static-node-stream-y-render-to-pipeable-stream.json │ ├── que-diferencia-hay-entre-use-effect-y-use-layout-effect.json │ ├── que-es-el-binding.json │ ├── que-es-el-ciclo-de-vida-de-un-componente-en-react.json │ ├── que-es-el-compound-components-pattern.json │ ├── que-es-el-contexto-en-react-como-puedo-crearlo-y-consumirlo.json │ ├── que-es-el-estado-en-react.json │ ├── que-es-el-hook-use-debug-value.json │ ├── que-es-el-profiler-en-react.json │ ├── que-es-el-renderizado-condicional-en-react.json │ ├── que-es-el-renderizado-de-listas-en-react.json │ ├── que-es-el-server-side-rendering-y-que-ventajas-tiene.json │ ├── que-es-el-strict-mode-en-react.json │ ├── que-es-el-synthetic-event-en-react.json │ ├── que-es-flush-sync-en-react.json │ ├── que-es-flux.json │ ├── que-es-jsx.json │ ├── que-es-la-hidratacion-hydration-en-react.json │ ├── que-es-react-dom.json │ ├── que-es-react.json │ ├── que-es-un-componente.json │ ├── que-es-y-para-que-sirve-la-prop-children-en-react.json │ ├── que-hace-el-hook-use-effect.json │ ├── que-hace-el-hook-use-id.json │ ├── que-hace-el-hook-use-layout-effect.json │ ├── que-hace-el-hook-use-state.json │ ├── que-java-script-necesito-para-aprender-react.json │ ├── que-problemas-crees-que-pueden-aparecer-en-una-aplicacion-al-querer-visualizar-listas-de-miles-millones-de-datos.json │ ├── que-quiere-decir-warning-each-child-in-a-list-should-have-a-unique-key-prop.json │ ├── que-significa-exactamente-que-sea-declarativo.json │ ├── que-significa-la-expresion-subir-el-estado.json │ ├── que-solucion-es-implementarias-para-evitar-problemas-de-rendimiento-al-trabajar-con-listas-de-miles-millones-de-datos.json │ ├── que-son-las-forward-refs.json │ ├── que-son-las-props-en-react.json │ ├── que-son-las-refs-en-react.json │ ├── que-son-las-render-props.json │ ├── que-son-los-componentes-stateless.json │ ├── que-son-los-error-boundaries-en-react.json │ ├── que-son-los-fragments-en-react.json │ ├── que-son-los-high-order-components-hoc.json │ ├── que-son-los-hooks.json │ ├── que-son-los-portales-en-react.json │ ├── que-son-mejores-los-componentes-de-clase-o-los-componentes-funcionales.json │ ├── react-hook-use-xxx-is-called-conditionally-react-hooks-must-be-called-in-the-exact-same-order-in-every-component-render.json │ ├── se-puede-inicializar-un-estado-con-el-valor-de-una-prop-que-pasa-si-lo-haces-y-que-hay-que-tener-en-cuenta.json │ ├── solo-se-pueden-cargar-componentes-de-forma-dinamica-si-se-exportan-por-defecto.json │ ├── sun.png │ └── too-many-re-renders-react-limits-the-number-of-renders-to-prevent-an-infinite-loop.json ├── cual-es-el-proposito-del-atributo-key-en-react-y-por-que-es-importante-usarlo-correctamente-al-renderizar-listas-de-elementos.json ├── cual-es-la-diferencia-entre-componente-y-elemento-en-react.json ├── cual-es-la-diferencia-entre-use-callback-y-use-memo.json ├── cuales-son-las-caracteristicas-principales-de-react.json ├── cuales-son-las-reglas-de-los-hooks-en-react.json ├── cuando-y-por-que-es-recomendable-importar-componentes-de-forma-dinamica.json ├── cuantos-use-effect-puede-tener-un-componente.json ├── es-buena-idea-usar-siempre-use-callback-para-optimizar-nuestros-componentes.json ├── es-buena-idea-usar-siempre-use-memo-para-optimizar-nuestros-componentes.json ├── es-react-una-biblioteca-o-un-framework-por-que.json ├── explica-casos-de-uso-del-hook-use-effect.json ├── favicon.dark.ico ├── favicon.ico ├── moon.png ├── og.png ├── para-que-sirve-el-hook-use-callback.json ├── para-que-sirve-el-hook-use-deferred-value.json ├── para-que-sirve-el-hook-use-imperative-handle.json ├── para-que-sirve-el-hook-use-memo.json ├── para-que-sirve-el-metodo-clone-element-de-react.json ├── para-que-sirve-el-metodo-render-to-readable-stream.json ├── por-que-debemos-utilizar-una-funcion-para-actualizar-el-estado-de-react.json ├── por-que-es-recomendable-exportar-los-componentes-de-react-de-forma-nombrada.json ├── por-que-es-recomendable-usar-fragment-en-vez-de-un-div.json ├── por-que-no-podemos-usar-un-if-en-el-renderizado-de-un-componente.json ├── por-que-puede-ser-mala-idea-pasar-siempre-todas-las-props-de-un-objeto-a-un-componente.json ├── por-que-puede-ser-mala-practica-usar-el-index-como-key-en-un-listado-de-react.json ├── por-que-strict-mode-renderiza-dos-veces-la-aplicacion.json ├── puedes-poner-un-ejemplo-de-efectos-colaterales-en-react.json ├── que-diferencia-existe-entre-shadow-dom-y-virtual-dom.json ├── que-diferencia-hay-entre-componentes-controlados-y-no-controlados-que-ventajas-y-desventajas-tienen.json ├── que-diferencia-hay-entre-props-y-state.json ├── que-diferencia-hay-entre-render-to-static-node-stream-y-render-to-pipeable-stream.json ├── que-diferencia-hay-entre-use-effect-y-use-layout-effect.json ├── que-es-el-binding.json ├── que-es-el-ciclo-de-vida-de-un-componente-en-react.json ├── que-es-el-compound-components-pattern.json ├── que-es-el-contexto-en-react-como-puedo-crearlo-y-consumirlo.json ├── que-es-el-estado-en-react.json ├── que-es-el-hook-use-debug-value.json ├── que-es-el-profiler-en-react.json ├── que-es-el-renderizado-condicional-en-react.json ├── que-es-el-renderizado-de-listas-en-react.json ├── que-es-el-server-side-rendering-y-que-ventajas-tiene.json ├── que-es-el-strict-mode-en-react.json ├── que-es-el-synthetic-event-en-react.json ├── que-es-flush-sync-en-react.json ├── que-es-flux.json ├── que-es-jsx.json ├── que-es-la-hidratacion-hydration-en-react.json ├── que-es-react-dom.json ├── que-es-react.json ├── que-es-un-componente.json ├── que-es-y-para-que-sirve-la-prop-children-en-react.json ├── que-hace-el-hook-use-effect.json ├── que-hace-el-hook-use-id.json ├── que-hace-el-hook-use-layout-effect.json ├── que-hace-el-hook-use-state.json ├── que-java-script-necesito-para-aprender-react.json ├── que-problemas-crees-que-pueden-aparecer-en-una-aplicacion-al-querer-visualizar-listas-de-miles-millones-de-datos.json ├── que-quiere-decir-warning-each-child-in-a-list-should-have-a-unique-key-prop.json ├── que-significa-exactamente-que-sea-declarativo.json ├── que-significa-la-expresion-subir-el-estado.json ├── que-solucion-es-implementarias-para-evitar-problemas-de-rendimiento-al-trabajar-con-listas-de-miles-millones-de-datos.json ├── que-son-las-forward-refs.json ├── que-son-las-props-en-react.json ├── que-son-las-refs-en-react.json ├── que-son-las-render-props.json ├── que-son-los-componentes-stateless.json ├── que-son-los-error-boundaries-en-react.json ├── que-son-los-fragments-en-react.json ├── que-son-los-high-order-components-hoc.json ├── que-son-los-hooks.json ├── que-son-los-portales-en-react.json ├── que-son-mejores-los-componentes-de-clase-o-los-componentes-funcionales.json ├── react-hook-use-xxx-is-called-conditionally-react-hooks-must-be-called-in-the-exact-same-order-in-every-component-render.json ├── react.svg ├── robots.txt ├── se-puede-inicializar-un-estado-con-el-valor-de-una-prop-que-pasa-si-lo-haces-y-que-hay-que-tener-en-cuenta.json ├── solo-se-pueden-cargar-componentes-de-forma-dinamica-si-se-exportan-por-defecto.json ├── sun.png └── too-many-re-renders-react-limits-the-number-of-renders-to-prevent-an-infinite-loop.json ├── pull_request_template.md ├── scripts ├── lint.mjs └── markdownToJson.mjs ├── tailwind.config.js ├── tsconfig.json └── utils └── posts.js /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | .pnpm-debug.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | 38 | package-lock.json 39 | dist -------------------------------------------------------------------------------- /.markdownlint.json: -------------------------------------------------------------------------------- 1 | { 2 | "default": true, 3 | "line-length": false, 4 | "no-inline-html": false, 5 | "first-line-h1": false 6 | } 7 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 22 2 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false, 3 | "singleQuote": true, 4 | "jsxSingleQuote": true, 5 | "tabWidth": 2, 6 | "printWidth": 80, 7 | "trailingComma": "es5", 8 | "arrowParens": "avoid", 9 | "bracketSpacing": true, 10 | "endOfLine": "lf" 11 | } 12 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["DavidAnson.vscode-markdownlint"] 3 | } 4 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "[markdown]": { 3 | "editor.formatOnSave": true, 4 | "editor.formatOnPaste": true 5 | }, 6 | "editor.codeActionsOnSave": { 7 | "source.fixAll.markdownlint": "explicit" 8 | }, 9 | "markdownlint.config": { 10 | "default": true, 11 | "line-length": false, 12 | "no-inline-html": false 13 | }, 14 | "typescript.tsdk": "node_modules/typescript/lib", 15 | "typescript.enablePromptUseWorkspaceTsdk": true 16 | } 17 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contribuciones 2 | 3 | Para editar un fichero, primero entra en la pestaña _Pull Requests_ para comprobar que nadie está añadiendo la misma pregunta. 4 | 5 | Para mejor organización, sólo debe añadirse una pregunta por Pull Requests y así evitar conflictos. 6 | 7 | ## ¿Qué preguntas se pueden añadir? 8 | 9 | Se buscan preguntas que pueden hacerte en una entrevista técnica de React. Las preguntas deben estar enfocadas a un problema o concepto, y deben tener relación directa con React. 10 | 11 | ## Estilo de las preguntas 12 | 13 | - Usa una respuesta lo más concisa posible y aporta ejemplos siempre que sea necesario. 14 | - No copies y pegues respuestas de otros sitios. 15 | - Aporta links de referencia a documentación, ejemplos, tweets o vídeos siempre que sea posible. 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Miguel Ángel Durán 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /app/Title.jsx: -------------------------------------------------------------------------------- 1 | export function Title({ as = 'h1', children }) { 2 | const Tag = as 3 | return {children} 4 | } 5 | -------------------------------------------------------------------------------- /app/[post]/Title.jsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { useEffect } from 'react' 4 | 5 | export function Title({ children }) { 6 | useEffect(() => { 7 | document.title = children 8 | }, [children]) 9 | 10 | return null 11 | } 12 | -------------------------------------------------------------------------------- /app/[post]/page.jsx: -------------------------------------------------------------------------------- 1 | import Link from 'next/link.js' 2 | import { fetchPost, listPosts } from '../../utils/posts.js' 3 | import './HighlightCode.css' 4 | import { Pill } from '../components/Pill.jsx' 5 | import { ButtonRead } from '../components/ButtonRead.jsx' 6 | 7 | export async function generateStaticParams() { 8 | return listPosts() 9 | } 10 | 11 | export async function generateMetadata(props) { 12 | const params = await props.params 13 | 14 | const { post } = params 15 | 16 | const { title, content } = await fetchPost(post) 17 | 18 | return { 19 | title, 20 | description: content, 21 | ogImage: 'https://reactjs.wiki/og.png', 22 | } 23 | } 24 | 25 | export default async function Post(props) { 26 | const params = await props.params 27 | const { post } = params 28 | const { content, level, title, prev, next } = await fetchPost(post) 29 | 30 | return ( 31 | <> 32 |
33 |
34 | 35 | 36 |
37 |

41 | {title} 42 |

43 |
44 |
48 | 60 | 61 | ) 62 | } 63 | -------------------------------------------------------------------------------- /app/api/search/route.ts: -------------------------------------------------------------------------------- 1 | import { NextResponse } from 'next/server' 2 | import Fuse from 'fuse.js' 3 | import { readIndex } from '../../../utils/posts.js' 4 | 5 | export const runtime = 'edge' 6 | 7 | // Define the handler for GET requests 8 | export async function GET(req: Request) { 9 | const { searchParams } = new URL(req.url) 10 | const q = searchParams.get('q') ?? '' 11 | 12 | const search = Array.isArray(q) ? q.join(' ') : q 13 | 14 | const index = await readIndex() 15 | 16 | const fuse = new Fuse(index, { 17 | keys: ['text'], 18 | includeScore: true, 19 | includeMatches: true, 20 | minMatchCharLength: 2, 21 | }) 22 | 23 | const results = fuse.search(search).slice(0, 5) 24 | 25 | console.log(results) 26 | 27 | // Return the results as a JSON response 28 | return NextResponse.json(results) 29 | } 30 | -------------------------------------------------------------------------------- /app/components/ButtonRead.jsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { useState, useEffect, useCallback } from 'react' 4 | import { useEventListener } from '../../hooks/useEventListener' 5 | 6 | export function ButtonRead({ title }) { 7 | const [isFavorite, setIsRead] = useState(false) 8 | 9 | useEffect(() => { 10 | const readStorage = JSON.parse(window.localStorage.getItem('read')) || [] 11 | setIsRead(readStorage.includes(title)) 12 | }, [title]) 13 | 14 | const handlerStorageListener = useCallback( 15 | event => { 16 | if (event.key === 'read') { 17 | setIsRead(JSON.parse(event.newValue).includes(title)) 18 | } 19 | }, 20 | [title] 21 | ) 22 | 23 | useEventListener({ 24 | eventName: 'storage', 25 | handler: handlerStorageListener, 26 | }) 27 | 28 | const handleSetRead = title => { 29 | if (title) { 30 | const read = JSON.parse(window.localStorage.getItem('read')) || [] 31 | const isFavorite = read.includes(title) 32 | if (isFavorite) { 33 | read.splice(read.indexOf(title), 1) 34 | setIsRead(false) 35 | } else { 36 | read.push(title) 37 | setIsRead(true) 38 | } 39 | window.localStorage.setItem('read', JSON.stringify(read)) 40 | } 41 | } 42 | 43 | const color = !isFavorite 44 | ? 'dark:bg-secondry bg-white' 45 | : 'dark:text-primary bg-green-200' 46 | return ( 47 |
48 | 54 |
55 | ) 56 | } 57 | -------------------------------------------------------------------------------- /app/components/BuyBook.jsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { BookCover } from './BookCover.tsx' 4 | import Image from 'next/image.js' 5 | 6 | export const BuyBook = () => { 7 | return ( 8 |
9 |
10 | 15 | 16 | Compra el libro 17 | 18 | 19 | Portada del libro de Preguntas de React 25 | 26 | 27 |
28 |
29 | ) 30 | } 31 | -------------------------------------------------------------------------------- /app/components/Card.jsx: -------------------------------------------------------------------------------- 1 | import Link from 'next/link' 2 | import { Pill } from './Pill.jsx' 3 | 4 | export function Card({ title, excerpt, slug, level }) { 5 | return ( 6 | 10 |
11 | 12 |

{title}

13 |

{excerpt}

14 |

Leer más...

15 |
16 | 17 | ) 18 | } 19 | -------------------------------------------------------------------------------- /app/components/Footer.jsx: -------------------------------------------------------------------------------- 1 | export async function Footer() { 2 | return ( 3 | 45 | ) 46 | } 47 | -------------------------------------------------------------------------------- /app/components/Head.jsx: -------------------------------------------------------------------------------- 1 | export const Head = ({ title, description, ogImage }) => { 2 | return ( 3 | <> 4 | {title} 5 | 6 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 26 | 31 | 32 | ) 33 | } 34 | -------------------------------------------------------------------------------- /app/components/ListOfQuestions.jsx: -------------------------------------------------------------------------------- 1 | import { readIndex } from '../../utils/posts.js' 2 | 3 | import Link from 'next/link' 4 | 5 | const getListOfQuestions = async () => { 6 | const questions = await readIndex() 7 | return questions 8 | } 9 | 10 | export async function ListOfQuestions() { 11 | const questions = await getListOfQuestions() 12 | 13 | return ( 14 | 26 | ) 27 | } 28 | -------------------------------------------------------------------------------- /app/components/Pill.jsx: -------------------------------------------------------------------------------- 1 | import { LEVELS } from '../constants.js' 2 | 3 | const LITERALS = { 4 | [LEVELS.EASY]: 'Principiante', 5 | [LEVELS.MEDIUM]: 'Intermedio', 6 | [LEVELS.HARD]: 'Avanzado', 7 | [LEVELS.ERRORS]: 'Errores típicos de React', 8 | } 9 | 10 | const COLORS = { 11 | [LEVELS.EASY]: 'text-green-600', 12 | [LEVELS.MEDIUM]: 'text-yellow-600', 13 | [LEVELS.HARD]: 'text-blue-600', 14 | [LEVELS.ERRORS]: 'text-red-600', 15 | } 16 | 17 | export function Pill({ level }) { 18 | const color = COLORS[level] ?? COLORS[LEVELS.EASY] 19 | const literal = LITERALS[level] ?? LITERALS[LEVELS.EASY] 20 | 21 | return ( 22 |
23 | 26 | {literal} 27 | 28 |
29 | ) 30 | } 31 | -------------------------------------------------------------------------------- /app/components/SearchIcon.jsx: -------------------------------------------------------------------------------- 1 | export function SearchIcon({ className }) { 2 | return ( 3 | 15 | 16 | 17 | 18 | ) 19 | } 20 | -------------------------------------------------------------------------------- /app/components/Stars.jsx: -------------------------------------------------------------------------------- 1 | export function Stars({ stars = 6379 }) { 2 | const formatNumber = number => { 3 | if (number >= 1000) { 4 | return `${(number / 1000).toFixed(1)}K` 5 | } 6 | return number 7 | } 8 | 9 | return ( 10 | 16 | 17 | 29 | Star 30 | 31 | 32 | 33 | {formatNumber(stars)} 34 | 35 | 36 | ) 37 | } 38 | -------------------------------------------------------------------------------- /app/components/ThemeToggle.jsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | import Image from 'next/image' 3 | import { useContext } from 'react' 4 | import { ThemeContext } from '../../context/ThemeContext' 5 | 6 | const ThemeToggle = () => { 7 | const { toggle, theme } = useContext(ThemeContext) 8 | 9 | return ( 10 |
19 | 20 |
28 | 29 |
30 | ) 31 | } 32 | 33 | export default ThemeToggle 34 | -------------------------------------------------------------------------------- /app/components/Title.jsx: -------------------------------------------------------------------------------- 1 | export function Title({ isHome }) { 2 | return ( 3 |

6 | Preguntas típicas de React.js 7 |

8 | ) 9 | } 10 | -------------------------------------------------------------------------------- /app/constants.js: -------------------------------------------------------------------------------- 1 | export const LEVELS = { 2 | EASY: 0, 3 | MEDIUM: 1, 4 | HARD: 2, 5 | ERRORS: -1, 6 | } 7 | -------------------------------------------------------------------------------- /app/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | -------------------------------------------------------------------------------- /app/layout.jsx: -------------------------------------------------------------------------------- 1 | import './globals.css' 2 | import { Space_Grotesk as SpaceGrotesk } from 'next/font/google' 3 | import { Header } from './components/Header.jsx' 4 | import { Footer } from './components/Footer.jsx' 5 | import { BuyBook } from './components/BuyBook.jsx' 6 | import { ThemeContextProvider } from '../context/ThemeContext.jsx' 7 | import ThemeProvider from '../provider/ThemeProvider.jsx' 8 | 9 | const spaceGrotesk = SpaceGrotesk({ 10 | weight: ['400', '700'], 11 | subsets: ['latin'], 12 | }) 13 | 14 | const fetchGitHubStars = () => { 15 | return fetch( 16 | 'https://api.github.com/repos/midudev/preguntas-entrevista-react' 17 | ) 18 | .then(res => res.json()) 19 | .then(response => response.stargazers_count) 20 | } 21 | 22 | export default async function RootLayout({ children }) { 23 | const stars = await fetchGitHubStars() 24 | 25 | return ( 26 | 27 | 28 | 29 | 30 |
31 | 44 | 45 | 46 | 47 | 48 | ) 49 | } 50 | -------------------------------------------------------------------------------- /app/page.tsx: -------------------------------------------------------------------------------- 1 | import type { Metadata } from 'next' 2 | 3 | import { Card } from './components/Card.jsx' 4 | import { ListOfQuestions } from './components/ListOfQuestions.jsx' 5 | import { LEVELS } from './constants.js' 6 | 7 | export const metadata: Metadata = { 8 | title: 'React.js Wiki - Preguntas típicas con respuesta y solución', 9 | description: 'Preguntas típicas sobre React.js con respuesta y solución', 10 | openGraph: { 11 | images: ['https://reactjs.wiki/og.png'], 12 | }, 13 | } 14 | 15 | export default function Page() { 16 | return ( 17 | <> 18 |

19 | Las preguntas más buscadas... 20 |

21 |
22 | 28 | 34 | 40 | 46 | 52 | 58 |
59 |

60 | Todas las preguntas sobre React disponibles 61 |

62 | 63 | 64 | ) 65 | } 66 | -------------------------------------------------------------------------------- /assets/space-grotesk.bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midudev/preguntas-entrevista-react/5b0737a8503b34046fc0cb0583a6b9b6eb4a2ba7/assets/space-grotesk.bold.ttf -------------------------------------------------------------------------------- /context/ThemeContext.jsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | import { createContext, useEffect, useState } from 'react' 3 | 4 | export const ThemeContext = createContext() 5 | 6 | const getFromLocalStorage = () => { 7 | if (typeof window !== 'undefined') { 8 | const value = window.localStorage.getItem('theme') 9 | return value || 'light' 10 | } 11 | } 12 | 13 | export const ThemeContextProvider = ({ children }) => { 14 | const [theme, setTheme] = useState(() => { 15 | return getFromLocalStorage() 16 | }) 17 | 18 | const toggle = () => { 19 | setTheme(theme === 'light' ? 'dark' : 'light') 20 | } 21 | 22 | useEffect(() => { 23 | window.localStorage.setItem('theme', theme) 24 | }, [theme]) 25 | 26 | return ( 27 | 28 | {children} 29 | 30 | ) 31 | } 32 | -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | module.exports = require('neostandard')({ 4 | noStyle: true, 5 | }) 6 | -------------------------------------------------------------------------------- /hooks/useEventListener.ts: -------------------------------------------------------------------------------- 1 | import { useEffect } from 'react' 2 | 3 | type UseEventListenerProps = { 4 | eventName: string 5 | handler: (event: Event) => void 6 | } 7 | export const useEventListener = ({ 8 | eventName, 9 | handler, 10 | }: UseEventListenerProps) => { 11 | useEffect(() => { 12 | window.addEventListener(eventName, event => { 13 | handler(event) 14 | }) 15 | 16 | return () => { 17 | window.removeEventListener(eventName, () => {}) 18 | } 19 | }, [eventName, handler]) 20 | 21 | return null 22 | } 23 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | reactStrictMode: true, 4 | eslint: { 5 | // Warning: This allows production builds to successfully complete even if 6 | // your project has ESLint errors. 7 | ignoreDuringBuilds: true, 8 | }, 9 | } 10 | 11 | module.exports = nextConfig 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "preguntas-entrevista-react", 3 | "version": "1.0.1", 4 | "description": "", 5 | "private": true, 6 | "engines": { 7 | "node": "22.x" 8 | }, 9 | "scripts": { 10 | "markdown:lint": "node scripts/lint.mjs", 11 | "dev": "next dev --turbopack", 12 | "build": "node scripts/markdownToJson.mjs && next build", 13 | "start": "next start", 14 | "prettier": "prettier --write .", 15 | "lint": "eslint ." 16 | }, 17 | "repository": { 18 | "type": "git", 19 | "url": "git+https://github.com/midudev/preguntas-entrevista-react.git" 20 | }, 21 | "bugs": { 22 | "url": "https://github.com/midudev/preguntas-entrevista-react/issues" 23 | }, 24 | "homepage": "https://github.com/midudev/preguntas-entrevista-react#readme", 25 | "devDependencies": { 26 | "@types/node": "22.5.5", 27 | "@types/react": "19.1.3", 28 | "autoprefixer": "10.4.21", 29 | "eslint": "9.26.0", 30 | "eslint-config-next": "15.3.1", 31 | "markdownlint": "0.38.0", 32 | "postcss": "8.4.49", 33 | "tailwindcss": "3.4.17", 34 | "typescript": "5.8.3" 35 | }, 36 | "dependencies": { 37 | "@headlessui/react": "2.2.2", 38 | "@sindresorhus/slugify": "2.2.1", 39 | "@vercel/og": "0.6.8", 40 | "framer-motion": "11.18.2", 41 | "fs-extra": "11.3.0", 42 | "fuse.js": "7.1.0", 43 | "just-debounce-it": "3.2.0", 44 | "marked": "14.1.1", 45 | "neostandard": "^0.12.1", 46 | "next": "15.3.1", 47 | "prettier": "^3.5.3", 48 | "prismjs": "1.30.0", 49 | "react": "19.1.0", 50 | "react-dom": "19.1.0", 51 | "react-github-btn": "1.4.0" 52 | }, 53 | "pnpm": { 54 | "overrides": { 55 | "@types/react": "19.1.3" 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /provider/ThemeProvider.jsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | import { ThemeContext } from '../context/ThemeContext' 3 | import React, { useContext, useEffect, useState } from 'react' 4 | 5 | const ThemeProvider = ({ children }) => { 6 | const { theme } = useContext(ThemeContext) 7 | const [mounted, setMounted] = useState(false) 8 | 9 | useEffect(() => { 10 | setMounted(true) 11 | }, []) 12 | 13 | if (mounted) { 14 | return
{children}
15 | } 16 | } 17 | 18 | export default ThemeProvider 19 | -------------------------------------------------------------------------------- /public/book.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midudev/preguntas-entrevista-react/5b0737a8503b34046fc0cb0583a6b9b6eb4a2ba7/public/book.png -------------------------------------------------------------------------------- /public/como-anadir-un-evento-a-un-componente-en-react.json: -------------------------------------------------------------------------------- 1 | {"id":"como-anadir-un-evento-a-un-componente-en-react","level":0,"title":"¿Cómo añadir un evento a un componente en React?","content":"

Para añadir un evento a un componente en React usamos la sintaxis on y el nombre del evento nativo del navegador en camelCase:

\n
function Button({ text, onClick }) {\n  return <button onClick={onClick}>{text}</button>\n}
\n\n

En este caso, el componente Button recibe una prop onClick que es una función. Cuando el usuario hace clic en el botón, se ejecuta la función onClick.

\n
\n"} 2 | -------------------------------------------------------------------------------- /public/como-crear-un-componente-en-react.json: -------------------------------------------------------------------------------- 1 | {"id":"como-crear-un-componente-en-react","level":0,"title":"¿Cómo crear un componente en React?","content":"

Los componentes en React son funciones o clases que devuelven un elemento de React. Hoy en día lo más recomendado es usar funciones:

\n
function HelloWorld() {\n  return <h1>Hello World!</h1>\n}
\n\n

Pero también puedes usar una clase para crear un componente React:

\n
import { Component } from 'react'\n\nclass HelloWorld extends Component {\n  render() {\n    return <h1>Hello World!</h1>\n  }\n}
\n\n

Lo importante es que el nombre de la función o clase empiece con una letra mayúscula. Esto es necesario para que React pueda distinguir entre componentes y elementos HTML.

\n
\n"} 2 | -------------------------------------------------------------------------------- /public/como-mantener-los-componentes-puros-y-que-ventajas-tiene.json: -------------------------------------------------------------------------------- 1 | {"id":"como-mantener-los-componentes-puros-y-que-ventajas-tiene","level":1,"title":"¿Cómo mantener los componentes puros y qué ventajas tiene?","content":"

Los componentes puros son aquellos que no tienen estado y que no tienen efectos secundarios. Esto quiere decir que no tienen ningún tipo de lógica que no sea la de renderizar la interfaz.

\n

Son más fáciles de testear y de mantener. Además, son más fáciles de entender porque no tienen lógica compleja.

\n

Para crear un componente puro en React usamos una function:

\n
function Button({ text }) {\n  return <button>{text}</button>\n}
\n\n

En este caso, el componente Button recibe una prop text que es un string. El componente Button renderiza un botón con el texto que recibe en la prop text.

\n
\n"} 2 | -------------------------------------------------------------------------------- /public/como-podemos-ejecutar-codigo-cuando-el-componente-se-desmonta-del-arbol.json: -------------------------------------------------------------------------------- 1 | {"id":"como-podemos-ejecutar-codigo-cuando-el-componente-se-desmonta-del-arbol","level":1,"title":"¿Cómo podemos ejecutar código cuando el componente se desmonta del árbol?","content":"

Podemos ejecutar código cuando el componente se desmonta usando el hook useEffect y dentro devolver una función con el código que queremos ejecutar. En este caso, la función que se pasa como primer parámetro del useEffect se ejecutará cuando el componente se monte, y la función que es retornada se ejecutará cuando se desmonte.

\n
import { useEffect } from 'react'\n\nfunction Component() {\n  useEffect(() => {\n    console.log('El componente se ha montado')\n\n    return () => {\n      console.log('El componente se ha desmontado')\n    }\n  }, [])\n\n  return <h1>Ejemplo</h1>\n}
\n\n

Esto es muy útil para limpiar recursos que se hayan creado en el componente, como por ejemplo, eventos del navegador o para cancelar peticiones a APIs.

\n
\n"} 2 | -------------------------------------------------------------------------------- /public/como-podemos-ejecutar-codigo-cuando-el-componente-se-monta.json: -------------------------------------------------------------------------------- 1 | {"id":"como-podemos-ejecutar-codigo-cuando-el-componente-se-monta","level":0,"title":"¿Cómo podemos ejecutar código cuando el componente se monta?","content":"

Podemos ejecutar código cuando el componente se monta usando el hook useEffect sin pasarle ninguna dependencia. En este caso, la función que se pasa como primer parámetro se ejecutará cuando el componente se monte.

\n
import { useEffect } from 'react'\n\nfunction Component() {\n  useEffect(() => {\n    console.log('El componente se ha montado')\n  }, [])\n\n  return <p>Abre la consola y re-dimensiona la ventana</p>\n}
\n\n\n\n
\n"} 2 | -------------------------------------------------------------------------------- /public/como-puedes-acceder-al-evento-nativo-del-navegador-en-react.json: -------------------------------------------------------------------------------- 1 | {"id":"como-puedes-acceder-al-evento-nativo-del-navegador-en-react","title":"¿Cómo puedes acceder al evento nativo del navegador en React?","content":"

React no expone el evento nativo del navegador. En su lugar, React crea un objeto sintético que se basa en el evento nativo del navegador llamado SyntheticEvent. Para acceder al evento nativo del navegador, debemos usar el atributo nativeEvent:

\n
function Button({ onClick }) {\n  return <button onClick={e => onClick(e.nativeEvent)}>Haz clic aquí</button>\n}
\n\n\n\n
\n"} 2 | -------------------------------------------------------------------------------- /public/como-puedes-aplicar-clases-css-a-un-componente-en-react-y-por-que-no-se-puede-usar-class.json: -------------------------------------------------------------------------------- 1 | {"id":"como-puedes-aplicar-clases-css-a-un-componente-en-react-y-por-que-no-se-puede-usar-class","level":0,"title":"¿Cómo puedes aplicar clases CSS a un componente en React y por qué no se puede usar `class`?","content":"

Para aplicar clases CSS a un componente en React usamos la prop className:

\n
function Button({ text }) {\n  return <button className='button'>{text}</button>\n}
\n\n

La razón por la que se llama className es porque class es una palabra reservada en JavaScript. Por eso, en JSX, tenemos que usar className para aplicar clases CSS.

\n
\n"} 2 | -------------------------------------------------------------------------------- /public/como-puedes-aplicar-estilos-en-linea-a-un-componente-en-react.json: -------------------------------------------------------------------------------- 1 | {"id":"como-puedes-aplicar-estilos-en-linea-a-un-componente-en-react","level":0,"title":"¿Cómo puedes aplicar estilos en línea a un componente en React?","content":"

Para aplicar estilos CSS en línea a un componente en React usamos la prop style. La diferencia de cómo lo haríamos con HTML, es que en React los estilos se pasan como un objeto y no como una cadena de texto (esto puede verse más claro con los dobles corchetes, los primeros para indicar que es una expresión JavaScript, y los segundos para crear el objeto):

\n
function Button({ text }) {\n  return <button style={{ color: 'red', borderRadius: '2px' }}>{text}</button>\n}
\n\n

Fíjate que, además, los nombres de las propiedades CSS están en camelCase.

\n
\n"} 2 | -------------------------------------------------------------------------------- /public/como-puedes-escribir-comentarios-en-react.json: -------------------------------------------------------------------------------- 1 | {"id":"como-puedes-escribir-comentarios-en-react","level":0,"title":"¿Cómo puedes escribir comentarios en React?","content":"

Si vas a escribir un comentario fuera del renderizado de un componente, puedes usar la sintaxis de comentarios de JavaScript sin problemas:

\n
function Button({ text }) {\n  // Esto es un comentario\n  /* Esto es un comentario\n  de varias líneas */\n\n  return <button>{text}</button>\n}
\n\n

Si vas a escribir un comentario dentro del renderizado de un componente, debes envolver el comentario en llaves y usar siempre la sintaxis de comentarios de bloque:

\n
function Button({ text }) {\n  return (\n    <button>\n      {/* Esto es un comentario en el render */}\n      {text}\n    </button>\n  )\n}
\n\n\n\n
\n"} 2 | -------------------------------------------------------------------------------- /public/como-puedes-exportar-multiples-componentes-de-un-mismo-archivo.json: -------------------------------------------------------------------------------- 1 | {"id":"como-puedes-exportar-multiples-componentes-de-un-mismo-archivo","level":1,"title":"¿Cómo puedes exportar múltiples componentes de un mismo archivo?","content":"

Para exportar múltiples componentes de un mismo archivo, podemos usar la exportación nombrada:

\n
// button.jsx\nexport function Button({ children }) {\n  return <button>{children}</button>\n}\n\nexport function ButtonSecondary({ children }) {\n  return <button class='btn-secondary'>{children}</button>\n}
\n\n\n\n
\n"} 2 | -------------------------------------------------------------------------------- /public/como-puedes-inicializar-un-proyecto-de-react-desde-cero.json: -------------------------------------------------------------------------------- 1 | {"id":"como-puedes-inicializar-un-proyecto-de-react-desde-cero","level":0,"title":"¿Cómo puedes inicializar un proyecto de React desde cero?","content":"

Existen diversas formas de inicializar un proyecto de React desde cero. Entre las más populares están:

\n\n
npm create vite@latest my-app -- --template react
\n\n\n
npx create-react-app my-app
\n\n
\n

La opción más popular y recomendada hoy en día es Vite. Fuente npm trends.

\n
\n

Usando un Framework, entre las más populares están:

\n\n
npx create-next-app@latest my-app
\n\n\n
npm init gatsby
\n\n
\n

La opción más popular y recomendada hoy en día es Nextjs. Fuente npm trends

\n
\n

Cada uno de ellos es un empaquetador de aplicaciones web. Se encargan de resolver las dependencias de tu proyecto, levantar un entorno de desarrollo que se refresca automáticamente con cada cambio y de empaquetar tu aplicación para producción con todos los archivos estáticos necesarios y mucho más.

\n
\n"} 2 | -------------------------------------------------------------------------------- /public/como-puedes-registrar-un-evento-en-la-fase-de-captura-en-react.json: -------------------------------------------------------------------------------- 1 | {"id":"como-puedes-registrar-un-evento-en-la-fase-de-captura-en-react","title":"¿Cómo puedes registrar un evento en la fase de captura en React?","content":"

En React, los eventos se registran en la fase de burbuja por defecto. Para registrar un evento en la fase de captura, debemos añadir Capture al nombre del evento:

\n
function Button({ onClick }) {\n  return <button onClickCapture={onClick}>Haz clic aquí</button>\n}
\n\n\n\n
\n"} 2 | -------------------------------------------------------------------------------- /public/como-puedo-validar-las-propiedades-de-un-objeto-con-prop-types.json: -------------------------------------------------------------------------------- 1 | {"id":"como-puedo-validar-las-propiedades-de-un-objeto-con-prop-types","level":1,"title":"¿Cómo puedo validar las propiedades de un objeto con PropTypes?","content":"

Para validar las propiedades de un objeto que se pasa como prop, podemos usar la propiedad shape de PropTypes:

\n
import PropTypes from 'prop-types'\n\nfunction App({ title }) {\n  const { text, color } = title\n  return <h1 style={{ color }}>{text}</h1>\n}\n\nApp.propTypes = {\n  title: PropTypes.shape({\n    text: PropTypes.string.isRequired,\n    color: PropTypes.string.isRequired,\n  }),\n}
\n\n\n\n
\n"} 2 | -------------------------------------------------------------------------------- /public/como-se-transforma-el-jsx.json: -------------------------------------------------------------------------------- 1 | {"id":"como-se-transforma-el-jsx","level":0,"title":"¿Cómo se transforma el JSX?","content":"

El JSX se transforma en código JavaScript compatible en el navegador usando un transpilador o compilador. El más famoso es a día de hoy Babel, que utiliza una serie de plugins para ser compatible con la transformación, pero existen otros como SWC.

\n

Puedes ver cómo se transforma el JSX en el playground de código de Babel.

\n

Hay casos especiales en los que un transpilador no es necesario. Por ejemplo, Deno tiene soporte nativo para la sintaxis JSX y no es necesario transformar el código para hacerlo compatible.

\n
\n"} 2 | -------------------------------------------------------------------------------- /public/content/como-anadir-un-evento-a-un-componente-en-react.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "como-anadir-un-evento-a-un-componente-en-react", 3 | "level": 0, 4 | "title": "¿Cómo añadir un evento a un componente en React?", 5 | "content": "

Para añadir un evento a un componente en React usamos la sintaxis on y el nombre del evento nativo del navegador en camelCase:

\n
function Button({ text, onClick }) {\n  return (\n    <button onClick={onClick}>\n      {text}\n    </button>\n  )\n}
\n\n

En este caso, el componente Button recibe una prop onClick que es una función. Cuando el usuario hace clic en el botón, se ejecuta la función onClick.

\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/como-crear-un-componente-en-react.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "como-crear-un-componente-en-react", 3 | "level": 0, 4 | "title": "¿Cómo crear un componente en React?", 5 | "content": "

Los componentes en React son funciones o clases que devuelven un elemento de React. Hoy en día lo más recomendado es usar funciones:

\n
function HelloWorld() {\n  return <h1>Hello World!</h1>\n}
\n\n

Pero también puedes usar una clase para crear un componente React:

\n
import { Component } from 'react'\n\nclass HelloWorld extends Component {\n  render() {\n    return <h1>Hello World!</h1>\n  }\n}
\n\n

Lo importante es que el nombre de la función o clase empiece con una letra mayúscula. Esto es necesario para que React pueda distinguir entre componentes y elementos HTML.

\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/como-mantener-los-componentes-puros-y-que-ventajas-tiene.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "como-mantener-los-componentes-puros-y-que-ventajas-tiene", 3 | "level": 1, 4 | "title": "¿Cómo mantener los componentes puros y qué ventajas tiene?", 5 | "content": "

Los componentes puros son aquellos que no tienen estado y que no tienen efectos secundarios. Esto quiere decir que no tienen ningún tipo de lógica que no sea la de renderizar la interfaz.

\n

Son más fáciles de testear y de mantener. Además, son más fáciles de entender porque no tienen lógica compleja.

\n

Para crear un componente puro en React usamos una function:

\n
function Button({ text }) {\n  return (\n    <button>\n      {text}\n    </button>\n  )\n}
\n\n

En este caso, el componente Button recibe una prop text que es un string. El componente Button renderiza un botón con el texto que recibe en la prop text.

\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/como-podemos-ejecutar-codigo-cuando-el-componente-se-desmonta-del-arbol.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "como-podemos-ejecutar-codigo-cuando-el-componente-se-desmonta-del-arbol", 3 | "level": 1, 4 | "title": "¿Cómo podemos ejecutar código cuando el componente se desmonta del árbol?", 5 | "content": "

Podemos ejecutar código cuando el componente se desmonta usando el hook useEffect y dentro devolver una función con el código que queremos ejecutar. En este caso, la función que se pasa como primer parámetro del useEffect se ejecutará cuando el componente se monte, y la función que es retornada se ejecutará cuando se desmonte.

\n
import { useEffect } from 'react'\n\nfunction Component() {\n  useEffect(() => {\n    console.log('El componente se ha montado')\n\n    return () => {\n      console.log('El componente se ha desmontado')\n    }\n  }, [])\n\n  return <h1>Ejemplo</h1>\n}
\n\n

Esto es muy útil para limpiar recursos que se hayan creado en el componente, como por ejemplo, eventos del navegador o para cancelar peticiones a APIs.

\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/como-podemos-ejecutar-codigo-cuando-el-componente-se-monta.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "como-podemos-ejecutar-codigo-cuando-el-componente-se-monta", 3 | "level": 0, 4 | "title": "¿Cómo podemos ejecutar código cuando el componente se monta?", 5 | "content": "

Podemos ejecutar código cuando el componente se monta usando el hook useEffect sin pasarle ninguna dependencia. En este caso, la función que se pasa como primer parámetro se ejecutará cuando el componente se monte.

\n
import { useEffect } from 'react'\n\nfunction Component() {\n  useEffect(() => {\n    console.log('El componente se ha montado')\n  }, [])\n\n  return (\n    <p>Abre la consola y re-dimensiona la ventana</p>\n  )\n}
\n\n\n\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/como-puedes-acceder-al-evento-nativo-del-navegador-en-react.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "como-puedes-acceder-al-evento-nativo-del-navegador-en-react", 3 | "title": "¿Cómo puedes acceder al evento nativo del navegador en React?", 4 | "content": "

React no expone el evento nativo del navegador. En su lugar, React crea un objeto sintético que se basa en el evento nativo del navegador llamado SyntheticEvent. Para acceder al evento nativo del navegador, debemos usar el atributo nativeEvent:

\n
function Button({ onClick }) {\n  return <button onClick={e => onClick(e.nativeEvent)}>Haz clic aquí</button>\n}
\n\n\n\n
\n" 5 | } 6 | -------------------------------------------------------------------------------- /public/content/como-puedes-aplicar-clases-css-a-un-componente-en-react-y-por-que-no-se-puede-usar-class.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "como-puedes-aplicar-clases-css-a-un-componente-en-react-y-por-que-no-se-puede-usar-class", 3 | "level": 0, 4 | "title": "¿Cómo puedes aplicar clases CSS a un componente en React y por qué no se puede usar `class`?", 5 | "content": "

Para aplicar clases CSS a un componente en React usamos la prop className:

\n
function Button({ text }) {\n  return (\n    <button className=\"button\">\n      {text}\n    </button>\n  )\n}
\n\n

La razón por la que se llama className es porque class es una palabra reservada en JavaScript. Por eso, en JSX, tenemos que usar className para aplicar clases CSS.

\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/como-puedes-aplicar-estilos-en-linea-a-un-componente-en-react.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "como-puedes-aplicar-estilos-en-linea-a-un-componente-en-react", 3 | "level": 0, 4 | "title": "¿Cómo puedes aplicar estilos en línea a un componente en React?", 5 | "content": "

Para aplicar estilos CSS en línea a un componente en React usamos la prop style. La diferencia de cómo lo haríamos con HTML, es que en React los estilos se pasan como un objeto y no como una cadena de texto (esto puede verse más claro con los dobles corchetes, los primeros para indicar que es una expresión JavaScript, y los segundos para crear el objeto):

\n
function Button({ text }) {\n  return (\n    <button style={{ color: 'red', borderRadius: '2px' }}>\n      {text}\n    </button>\n  )\n}
\n\n

Fíjate que, además, los nombres de las propiedades CSS están en camelCase.

\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/como-puedes-escribir-comentarios-en-react.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "como-puedes-escribir-comentarios-en-react", 3 | "level": 0, 4 | "title": "¿Cómo puedes escribir comentarios en React?", 5 | "content": "

Si vas a escribir un comentario fuera del renderizado de un componente, puedes usar la sintaxis de comentarios de JavaScript sin problemas:

\n
function Button({ text }) {\n  // Esto es un comentario\n  /* Esto es un comentario\n  de varias líneas */\n\n  return (\n    <button>\n      {text}\n    </button>\n  )\n}
\n\n

Si vas a escribir un comentario dentro del renderizado de un componente, debes envolver el comentario en llaves y usar siempre la sintaxis de comentarios de bloque:

\n
function Button({ text }) {\n  return (\n    <button>\n      {/* Esto es un comentario en el render */}\n      {text}\n    </button>\n  )\n}
\n\n\n\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/como-puedes-exportar-multiples-componentes-de-un-mismo-archivo.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "como-puedes-exportar-multiples-componentes-de-un-mismo-archivo", 3 | "level": 1, 4 | "title": "¿Cómo puedes exportar múltiples componentes de un mismo archivo?", 5 | "content": "

Para exportar múltiples componentes de un mismo archivo, podemos usar la exportación nombrada:

\n
// button.jsx\nexport function Button({children}) {\n  return <button>{children}</button>\n}\n\nexport function ButtonSecondary({children}) {\n  return <button class=\"btn-secondary\">{children}</button>\n}
\n\n\n\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/como-puedes-inicializar-un-proyecto-de-react-desde-cero.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "como-puedes-inicializar-un-proyecto-de-react-desde-cero", 3 | "level": 0, 4 | "title": "¿Cómo puedes inicializar un proyecto de React desde cero?", 5 | "content": "

Existen diversas formas de inicializar un proyecto de React desde cero. Entre las más populares están:

\n\n
npm create vite@latest my-app -- --template react
\n\n\n
npx create-react-app my-app
\n\n
\n

La opción más popular y recomendada hoy en día es Vite. Fuente npm trends.

\n
\n

Usando un Framework, entre las más populares están:

\n\n
npx create-next-app@latest my-app
\n\n\n
npm init gatsby
\n\n
\n

La opción más popular y recomendada hoy en día es Nextjs. Fuente npm trends

\n
\n

Cada uno de ellos es un empaquetador de aplicaciones web. Se encargan de resolver las dependencias de tu proyecto, levantar un entorno de desarrollo que se refresca automáticamente con cada cambio y de empaquetar tu aplicación para producción con todos los archivos estáticos necesarios y mucho más.

\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/como-puedes-registrar-un-evento-en-la-fase-de-captura-en-react.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "como-puedes-registrar-un-evento-en-la-fase-de-captura-en-react", 3 | "title": "¿Cómo puedes registrar un evento en la fase de captura en React?", 4 | "content": "

En React, los eventos se registran en la fase de burbuja por defecto. Para registrar un evento en la fase de captura, debemos añadir Capture al nombre del evento:

\n
function Button({ onClick }) {\n  return <button onClickCapture={onClick}>Haz clic aquí</button>\n}
\n\n\n\n
\n" 5 | } 6 | -------------------------------------------------------------------------------- /public/content/como-puedo-validar-las-propiedades-de-un-objeto-con-prop-types.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "como-puedo-validar-las-propiedades-de-un-objeto-con-prop-types", 3 | "level": 1, 4 | "title": "¿Cómo puedo validar las propiedades de un objeto con PropTypes?", 5 | "content": "

Para validar las propiedades de un objeto que se pasa como prop, podemos usar la propiedad shape de PropTypes:

\n
import PropTypes from \"prop-types\"\n\nfunction App({ title }) {\n  const { text, color } = title\n  return <h1 style={{ color }}>{text}</h1>\n}\n\nApp.propTypes = {\n  title: PropTypes.shape({\n    text: PropTypes.string.isRequired,\n    color: PropTypes.string.isRequired,\n  }),\n}
\n\n\n\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/como-se-transforma-el-jsx.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "como-se-transforma-el-jsx", 3 | "level": 0, 4 | "title": "¿Cómo se transforma el JSX?", 5 | "content": "

El JSX se transforma en código JavaScript compatible en el navegador usando un transpilador o compilador. El más famoso es a día de hoy Babel, que utiliza una serie de plugins para ser compatible con la transformación, pero existen otros como SWC.

\n

Puedes ver cómo se transforma el JSX en el playground de código de Babel.

\n

Hay casos especiales en los que un transpilador no es necesario. Por ejemplo, Deno tiene soporte nativo para la sintaxis JSX y no es necesario transformar el código para hacerlo compatible.

\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/counter.json: -------------------------------------------------------------------------------- 1 | {"total":105} 2 | -------------------------------------------------------------------------------- /public/content/cual-es-la-diferencia-entre-componente-y-elemento-en-react.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "cual-es-la-diferencia-entre-componente-y-elemento-en-react", 3 | "level": 0, 4 | "title": "¿Cuál es la diferencia entre componente y elemento en React?", 5 | "content": "

Un componente es una función o clase que recibe props y devuelve un elemento.\nUn elemento es un objeto que representa un nodo del DOM o una instancia de un componente de React.

\n
// Elemento que representa un nodo del DOM\n{\n  type: 'button',\n  props: {\n    className: 'button button-blue',\n    children: {\n      type: 'b',\n      props: {\n        children: 'OK!'\n      }\n    }\n  }\n}\n\n// Elemento que representa una instancia de un componente\n{\n  type: Button,\n  props: {\n    color: 'blue',\n    children: 'OK!'\n  }\n}
\n\n\n\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/cual-es-la-diferencia-entre-use-callback-y-use-memo.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "cual-es-la-diferencia-entre-use-callback-y-use-memo", 3 | "level": 1, 4 | "title": "¿Cuál es la diferencia entre `useCallback` y `useMemo`?", 5 | "content": "

La diferencia entre useCallback y useMemo es que useCallback memoriza una función y useMemo memoriza el resultado de una función.

\n

En cualquier caso, en realidad, useCallback es una versión especializada de useMemo. De hecho se puede simular la funcionalidad de useCallback con useMemo:

\n
const memoizedCallback = useMemo(() => {\n  return () => {\n    doSomething(a, b)\n  }\n}, [a, b])
\n\n\n\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/cuales-son-las-caracteristicas-principales-de-react.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "cuales-son-las-caracteristicas-principales-de-react", 3 | "level": 0, 4 | "title": "¿Cuáles son las características principales de React?", 5 | "content": "

Las características principales de React son:

\n
    \n
  • Componentes: React está basado en la componetización de la UI. La interfaz se divide en componentes independientes, que contienen su propio estado. Cuando el estado de un componente cambia, React vuelve a renderizar la interfaz.

    \n
  • \n
  • Virtual DOM: React usa un DOM virtual para renderizar los componentes. El DOM virtual es una representación en memoria del DOM real. Cuando el estado de un componente cambia, React vuelve a renderizar la interfaz. En lugar de modificar el DOM real, React modifica el DOM virtual y, a continuación, compara el DOM virtual con el DOM real. De esta forma, React sabe qué cambios se deben aplicar al DOM real.

    \n
  • \n
  • Declarativo: React es declarativo, lo que significa que no se especifica cómo se debe realizar una tarea, sino qué se debe realizar. Esto hace que el código sea más fácil de entender y de mantener.

    \n
  • \n
  • Unidireccional: React es unidireccional, lo que significa que los datos fluyen en una sola dirección. Los datos fluyen de los componentes padres a los componentes hijos.

    \n
  • \n
  • Universal: React se puede ejecutar tanto en el cliente como en el servidor. Además, puedes usar React Native para crear aplicaciones nativas para Android e iOS.

    \n
  • \n
\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/cuales-son-las-reglas-de-los-hooks-en-react.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "cuales-son-las-reglas-de-los-hooks-en-react", 3 | "level": 1, 4 | "title": "¿Cuáles son las reglas de los hooks en React?", 5 | "content": "

Los hooks en React tienen dos reglas fundamentales:

\n
    \n
  • Los hooks solo se pueden usar en componentes funcionales o custom hooks.
  • \n
  • Los hooks solo se pueden llamar en el nivel superior de un componente. No se pueden llamar dentro de bucles, condicionales o funciones anidadas.
  • \n
\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/cuantos-use-effect-puede-tener-un-componente.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "cuantos-use-effect-puede-tener-un-componente", 3 | "level": 1, 4 | "title": "¿Cuántos `useEffect` puede tener un componente?", 5 | "content": "

Aunque normalmente los componentes de React solo cuentan con un useEffect lo cierto es que podemos tener tantos useEffect como queramos en un componente. Cada uno de ellos se ejecutará cuando se renderice el componente o cuando cambien las dependencias del efecto.

\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/es-buena-idea-usar-siempre-use-callback-para-optimizar-nuestros-componentes.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "es-buena-idea-usar-siempre-use-callback-para-optimizar-nuestros-componentes", 3 | "level": 1, 4 | "title": "¿Es buena idea usar siempre `useCallback` para optimizar nuestros componentes?", 5 | "content": "

No. useCallback es una herramienta que nos permite optimizar nuestros componentes, pero no es una herramienta mágica que nos va a hacer que nuestros componentes sean más rápidos. A veces la creación de una función es tan rápida que no merece la pena memorizarla. Incluso, en algunos casos, puede ser más lento memorizarla que crearla de nuevo.

\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/es-buena-idea-usar-siempre-use-memo-para-optimizar-nuestros-componentes.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "es-buena-idea-usar-siempre-use-memo-para-optimizar-nuestros-componentes", 3 | "level": 1, 4 | "title": "¿Es buena idea usar siempre `useMemo` para optimizar nuestros componentes?", 5 | "content": "

No. useMemo es una herramienta que nos permite optimizar nuestros componentes, pero no es una herramienta mágica que nos va a hacer que nuestros componentes sean más rápidos. A veces el cálculo de un valor es tan rápido que no merece la pena memorizarlo. Incluso, en algunos casos, puede ser más lento memorizarlo que calcularlo de nuevo.

\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/es-react-una-biblioteca-o-un-framework-por-que.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "es-react-una-biblioteca-o-un-framework-por-que", 3 | "title": "¿Es React una biblioteca o un framework? ¿Por qué?", 4 | "content": "

Existe una fina línea hoy en día entre qué es una biblioteca o un framework. Oficialmente, React se autodenomina como biblioteca. Esto es porque para poder crear una aplicación completa, necesitas usar otras bibliotecas.

\n

Por ejemplo, React no ofrece un sistema de enrutado de aplicaciones oficial. Por ello, hay que usar una biblioteca como React Router o usar un framework como Next.js que ya incluye un sistema de enrutado.

\n

Tampoco puedes usar React para añadir las cabeceras que van en el <head> en tu aplicación, y también necesitarás otra biblioteca o framework para solucionar esto.

\n

Otra diferencia es que React no está opinionado sobre qué empaquetador de aplicaciones usar. En cambio Angular en su propio tutorial ya te indica que debes usar @angular/cli para crear una aplicación, en cambio React siempre te deja la libertad de elegir qué empaquetador usar y ofrece diferentes opciones.

\n

Aún así, existe gente que considera a React como un framework. Aunque no hay una definición oficial de qué es un framework, la mayoría de la gente considera que un framework es una biblioteca que incluye otras bibliotecas para crear una aplicación completa de forma opinionada y casi sin configuración.

\n

Por ejemplo, Next.js se podría considerar un framework de React porque incluye React, un sistema de enrutado, un sistema de renderizado del lado del servidor, etc.

\n
\n" 5 | } 6 | -------------------------------------------------------------------------------- /public/content/explica-casos-de-uso-del-hook-use-effect.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "explica-casos-de-uso-del-hook-use-effect", 3 | "level": 0, 4 | "title": "Explica casos de uso del hook `useEffect`", 5 | "content": "

Podemos usar el hook useEffect de diferentes formas, tales como:

\n
    \n
  • Ejecutar código cuando se renderiza el componente, cuando cambian las dependencias del efecto o cuando se desmonta el componente.
  • \n
  • Por eso puede ser útil para hacer llamadas a APIs, ya que sea nada más montar el componente o cuando cambian las dependencias.
  • \n
  • Realizar tracking de eventos, como Google Analytics, para saber qué páginas visitan los usuarios.
  • \n
  • Podemos validar un formulario para que cada vez que cambie el estado, podamos actualizar la UI y mostrar dónde están los errores.
  • \n
  • Podemos suscribirnos a eventos del navegador, como por ejemplo el evento resize para saber cuando el usuario cambia el tamaño de la ventana.
  • \n
\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/moon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midudev/preguntas-entrevista-react/5b0737a8503b34046fc0cb0583a6b9b6eb4a2ba7/public/content/moon.png -------------------------------------------------------------------------------- /public/content/por-que-debemos-utilizar-una-funcion-para-actualizar-el-estado-de-react.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "por-que-debemos-utilizar-una-funcion-para-actualizar-el-estado-de-react", 3 | "level": 1, 4 | "title": "¿Por qué debemos utilizar una función para actualizar el estado de React?", 5 | "content": "

A la hora de actualizar el estado de React, debemos utilizar la función que nos facilita el hook useState para actualizar el estado.

\n
const [count, setCount] = useState(0)\n\nsetCount(count + 1)
\n\n

¿Por qué es esto necesario? En primer lugar, el estado en React debe ser inmutable. Es decir, no podemos modificar el estado directamente, sino que debemos siempre crear un nuevo valor para el nuevo estado.

\n

Esto nos permite que la integridad de la UI respecto a los datos que renderiza siempre es correcta.

\n

Por otro lado, llamar a una función le permite a React saber que el estado ha cambiado y que debe re-renderizar el componente si es necesario. Además esto lo hace de forma asíncrona, por lo que podemos llamar a setCount tantas veces como queramos y React se encargará de actualizar el estado cuando lo considere oportuno.

\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/por-que-es-recomendable-usar-fragment-en-vez-de-un-div.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "por-que-es-recomendable-usar-fragment-en-vez-de-un-div", 3 | "level": 0, 4 | "title": "¿Por qué es recomendable usar Fragment en vez de un div?", 5 | "content": "

Las razones por las que es recomendable usar Fragment en vez de un div a la hora de envolver varios elementos son:

\n
    \n
  • Los div añaden un elemento extra al DOM, mientras que los Fragments no. Esto hace que el número de elementos HTML y la profundidad del DOM sea menor.
  • \n
  • Los elementos envueltos con Fragment son afectados directamente por las propiedades flex o grid de CSS de su elemento padre. Si usas un div es posible que tengas problemas con el alineamiento de los elementos.
  • \n
  • Los Fragments son más rápidos que los div ya que no tienen que ser renderizados.
  • \n
  • Los div aplican CSS por defecto (hace que lo que envuelve el div se comporte como un bloque al aplicar un display: block) mientras que los Fragment no aplican ningún estilo por defecto.
  • \n
\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/por-que-puede-ser-mala-idea-pasar-siempre-todas-las-props-de-un-objeto-a-un-componente.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "por-que-puede-ser-mala-idea-pasar-siempre-todas-las-props-de-un-objeto-a-un-componente", 3 | "level": 1, 4 | "title": "¿Por qué puede ser mala idea pasar siempre todas las props de un objeto a un componente?", 5 | "content": "

Digamos que tenemos un componente App que recibe un objeto props con todas las props que necesita:

\n
function App(props) {\n  return <h1>{props.title}</h1>\n}
\n\n

Y que tenemos otro componente Layout que recibe un objeto props con todas las props que necesita:

\n
function Layout(props) {\n  return (\n    <div>\n      <App {...props} />\n    </div>\n  )\n}
\n\n

En este caso, Layout está pasando todas las props que recibe a App. Esto puede ser una mala idea por varias razones:

\n
    \n
  • Si Layout recibe una prop que no necesita, la pasará a App y éste puede que no la use. Esto puede ser confuso para el que lea el código.
  • \n
\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/por-que-strict-mode-renderiza-dos-veces-la-aplicacion.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "por-que-strict-mode-renderiza-dos-veces-la-aplicacion", 3 | "title": "¿Por qué `StrictMode` renderiza dos veces la aplicación?", 4 | "content": "

Cuando el modo StrictMode está activado, React monta los componentes dos veces (el estado y el DOM se preserva). Esto ayuda a encontrar efectos que necesitan una limpieza o expone problemas con race conditions.

\n
\n" 5 | } 6 | -------------------------------------------------------------------------------- /public/content/que-diferencia-existe-entre-shadow-dom-y-virtual-dom.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "que-diferencia-existe-entre-shadow-dom-y-virtual-dom", 3 | "level": -1, 4 | "title": "¿Qué diferencia existe entre Shadow DOM y Virtual DOM?", 5 | "content": "

El Shadow DOM es una API del navegador que nos permite crear un árbol de nodos DOM independiente dentro de un elemento del DOM. Esto nos permite crear componentes que no interfieran con el resto de la aplicación. Se usa especialmente con Web Components.

\n

El Virtual DOM es una representación del DOM en memoria. Esta representación se crea cada vez que se produce un cambio en el DOM. Esto nos permite comparar el DOM actual con el DOM anterior y así determinar qué cambios se deben realizar en el DOM real. Lo usa React y otras bibliotecas para hacer el mínimo número de cambios en el DOM real.

\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/que-diferencia-hay-entre-props-y-state.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "que-diferencia-hay-entre-props-y-state", 3 | "level": 0, 4 | "title": "¿Qué diferencia hay entre props y state?", 5 | "content": "

Las props son un objeto que se pasan como argumentos de un componente padre a un componente hijo. Son inmutables y no se pueden modificar desde el componente hijo.

\n

El state es un valor que se define dentro de un componente. Su valor es inmutable (no se puede modificar directamente) pero se puede establecer un valor nuevo del estado para que React vuelva a renderizar el componente.

\n

Así que mientras tanto props como state afectan al renderizado del componente, su gestión es diferente.

\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/que-diferencia-hay-entre-render-to-static-node-stream-y-render-to-pipeable-stream.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "que-diferencia-hay-entre-render-to-static-node-stream-y-render-to-pipeable-stream", 3 | "title": "¿Qué diferencia hay entre `renderToStaticNodeStream()` y `renderToPipeableStream()`?", 4 | "content": "

renderToStaticNodeStream() devuelve un stream de nodos estáticos, esto significa que no añade atributos extras para el DOM que React usa internamente para poder lograr la hidratación del HTML en el cliente. Esto significa que no podrás hacer el HTML interactivo en el cliente, pero puede ser útil para páginas totalmente estáticas.

\n

renderToPipeableStream() devuelve un stream de nodos que contienen atributos del DOM extra para que React pueda hidratar el HTML en el cliente. Esto significa que podrás hacer el HTML interactivo en el cliente pero puede ser más lento que renderToStaticNodeStream().

\n
\n" 5 | } 6 | -------------------------------------------------------------------------------- /public/content/que-diferencia-hay-entre-use-effect-y-use-layout-effect.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "que-diferencia-hay-entre-use-effect-y-use-layout-effect", 3 | "level": 1, 4 | "title": "¿Qué diferencia hay entre `useEffect` y `useLayoutEffect`?", 5 | "content": "

Aunque ambos son muy parecidos, tienen una pequeña diferencia en el momento en el que se ejecutan.

\n

useLayoutEffect se ejecuta de forma síncrona inmediatamente después que React haya actualizado completamente el DOM tras el renderizado. Puede ser útil si necesitas recuperar un elemento del DOM y acceder a sus dimensiones o posición en pantalla.

\n

useEffect se ejecuta de forma asíncrona tras el renderizado, pero no asegura que el DOM se haya actualizado. Es decir, si necesitas recuperar un elemento del DOM y acceder a sus dimensiones o posición en pantalla, no podrás hacerlo con useEffect porque no tienes la garantía de que el DOM se haya actualizado.

\n

Normalmente, el 99% de las veces, vas a querer utilizar useEffect y, además, tiene mejor rendimiento, ya que no bloquea el renderizado.

\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/que-es-el-ciclo-de-vida-de-un-componente-en-react.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "que-es-el-ciclo-de-vida-de-un-componente-en-react", 3 | "level": 1, 4 | "title": "¿Qué es el ciclo de vida de un componente en React?", 5 | "content": "

En los componentes de clase, el ciclo de vida de un componente se divide en tres fases:

\n
    \n
  • Montaje: cuando el componente se añade al DOM.
  • \n
  • Actualización: cuando el componente se actualiza.
  • \n
  • Desmontaje: cuando el componente se elimina del DOM.
  • \n
\n

Dentro de este ciclo de vida, existe un conjunto de métodos que se ejecutan en el componente.

\n

Estos métodos se definen en la clase y se ejecutan en el orden que se muestran a continuación:

\n
    \n
  • constructor
  • \n
  • render
  • \n
  • componentDidMount
  • \n
  • componentDidUpdate
  • \n
  • componentWillUnmount
  • \n
\n

En cada uno de estos métodos podemos ejecutar código que nos permita controlar el comportamiento de nuestro componente.

\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/que-es-el-hook-use-debug-value.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "que-es-el-hook-use-debug-value", 3 | "title": "¿Qué es el hook `useDebugValue`?", 4 | "content": "

Nos permite mostrar un valor personalizado en la pestaña de React DevTools que nos permitirá depurar nuestro código.

\n
import { useDebugValue } from 'react'\n\nfunction useCustomHook() {\n  const value = 'custom value'\n  useDebugValue(value)\n  return value\n}
\n\n

En este ejemplo, el valor personalizado que se muestra en la pestaña de React DevTools es custom value.

\n

Aunque es útil para depurar, no se recomienda usar este hook en producción.

\n
\n" 5 | } 6 | -------------------------------------------------------------------------------- /public/content/que-es-el-renderizado-condicional-en-react.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "que-es-el-renderizado-condicional-en-react", 3 | "level": 0, 4 | "title": "¿Qué es el renderizado condicional en React?", 5 | "content": "

El renderizado condicional es la forma de mostrar un componente u otro dependiendo de una condición.

\n

Para hacer renderizado condicional en React usamos el operador ternario:

\n
function Button({ text }) {\n  return text\n    ? <button>{text}</button>\n    : null\n}
\n\n

En este caso, si la prop text existe, se renderiza el botón. Si no existe, no se renderiza nada.

\n

Es común encontrar implementaciones del renderizado condicional con el operador &&, del tipo:

\n
function List({ listArray }) {\n  return listArray?.length && listArray.map(item=>item)\n}
\n\n

Parece que tiene sentido... si el length es positivo (mayor a cero) pintamos el map. !Pues no! ❌ Cuidado, si tiene length de cero ya que se pintará en el navegador un 0.

\n

Es preferible utilizar el operador ternario. Kent C. Dodds tiene un artículo interesante hablando del tema. Use ternaries rather than && in JSX

\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/que-es-el-server-side-rendering-y-que-ventajas-tiene.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "que-es-el-server-side-rendering-y-que-ventajas-tiene", 3 | "level": 1, 4 | "title": "¿Qué es el Server Side Rendering y qué ventajas tiene?", 5 | "content": "

El Server Side Rendering es una técnica que consiste en renderizar el HTML en el servidor y enviarlo al cliente. Esto nos permite que el usuario vea la interfaz de la aplicación antes de que se cargue el JavaScript.

\n

Esta técnica nos permite mejorar la experiencia de usuario y mejorar el SEO de nuestra aplicación.

\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/que-es-el-strict-mode-en-react.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "que-es-el-strict-mode-en-react", 3 | "level": 1, 4 | "title": "¿Qué es el `StrictMode` en React?", 5 | "content": "

El StrictMode es un componente que nos permite activar algunas comprobaciones de desarrollo en React. Por ejemplo, detecta componentes que se renderizan de forma innecesaria o funcionalidades obsoletas que se están usando.

\n
import { StrictMode } from 'react'\n\nfunction App() {\n  return (\n    <StrictMode>\n      <Component />\n    </StrictMode>\n  )\n}
\n\n\n\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/que-es-el-synthetic-event-en-react.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "que-es-el-synthetic-event-en-react", 3 | "level": 1, 4 | "title": "¿Qué es el `SyntheticEvent` en React?", 5 | "content": "

El SyntheticEvent es una abstracción del evento nativo del navegador. Esto le permite a React tener un comportamiento consistente en todos los navegadores.

\n

Dentro del SyntheticEvent puede encontrarse una referencia al evento nativo en su atributo nativeEvent

\n
function App() {\n  function handleClick(event) {\n    console.log(event)\n  }\n\n  return <button onClick={handleClick}>Haz clic aquí</button>\n}
\n\n\n\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/que-es-flux.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "que-es-flux", 3 | "level": -1, 4 | "title": "¿Qué es Flux?", 5 | "content": "

Flux es un patrón de arquitectura de aplicaciones que se basa en un unidireccional de datos. En este patrón, los datos fluyen en una sola dirección: de las vistas a los stores.

\n

No es específico de React y se puede usar con cualquier librería de vistas. En este patrón, los stores son los encargados de almacenar los datos de la aplicación. Los stores emiten eventos cuando los datos cambian. Las vistas se suscriben a estos eventos para actualizar los datos.

\n

Esta arquitectura fue creada por Facebook para manejar la complejidad de sus aplicaciones. Redux se basó en este patrón para crear una biblioteca de gestión de estado global.

\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/que-es-jsx.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "que-es-jsx", 3 | "level": 0, 4 | "title": "¿Qué es JSX?", 5 | "content": "

React usa JSX para declarar qué debe renderizar. JSX es una extensión de JavaScript que permite escribir un código más cercano visualmente a HTML, que mejora la legibilidad del código y hace que sea más fácil de entender.

\n

Sin JSX, deberíamos usar React.createElement para crear los elementos de la interfaz manualmente de esta forma:

\n
import { createElement } from 'react'\n\nfunction Hello () { // un componente es una función! 👀\n  return React.createElement(\n    'h1', // elemento a renderizar\n     null, // atributos del elemento\n    'Hola Mundo 👋🌍!' // contenido del elemento\n  )\n}
\n\n

Esto es muy tedioso y poco legible. Por eso, React usa JSX para declarar qué debe renderizar. Por eso usamos JSX de esta forma:

\n
function Hello () {\n  return <h1>Hola Mundo 👋🌍!</h1>\n}
\n\n

Ambos códigos son equivalentes.

\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/que-es-la-hidratacion-hydration-en-react.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "que-es-la-hidratacion-hydration-en-react", 3 | "level": 1, 4 | "title": "¿Qué es la hidratación (hydration) en React?", 5 | "content": "

Cuando renderizamos nuestra aplicación en el servidor, React genera un HTML estático. Este HTML estático es simplemente un string que contiene el HTML que se va a mostrar en la página.

\n

Cuando el navegador recibe el HTML estático, lo renderiza en la página. Sin embargo, este HTML estático no tiene interactividad. No tiene eventos, no tiene lógica, no tiene estado, etc. Podríamos decir que no tiene vida.

\n

Para hacer que este HTML estático pueda ser interactivo, React necesita que el HTML estático se convierta en un árbol de componentes de React. Esto se llama hidratación.

\n

De esta forma, en el cliente, React reutiliza este HTML estático y se dedica a adjuntar los eventos a los elementos, ejecutar los efectos que tengamos en los componentes y conciliar el estado de los componentes.

\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/que-es-react-dom.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "que-es-react-dom", 3 | "level": 0, 4 | "title": "¿Qué es React DOM?", 5 | "content": "

React DOM es la librería que se encarga de renderizar los componentes de React para el navegador. Hay que tener en cuenta que React es una biblioteca que se puede usar en diferentes entornos (dispositivos móviles, apps de escritorio, terminal...).

\n

Mientras que la biblioteca de React, a secas, es el motor de creación de componentes, hooks, sistema de props y estado... React DOM es la librería que se encarga de renderizar los componentes de React específicamente en el navegador.

\n

React Native, por ejemplo, haría lo mismo, pero para dispositivos móviles.

\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/que-es-react.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "que-es-react", 3 | "level": 0, 4 | "title": "¿Qué es React?", 5 | "content": "

¿Qué es React?

\n

React es una biblioteca de JavaScript de código abierto para construir interfaces de usuario. Está basada en la componetización de la UI: la interfaz se divide en componentes independientes, que contienen su propio estado. Cuando el estado de un componente cambia, React vuelve a renderizar la interfaz.

\n

Esto hace que React sea una herramienta muy útil para construir interfaces complejas, ya que permite dividir la interfaz en piezas más pequeñas y reutilizables.

\n

Fue creada en 2011 por Jordan Walke, un ingeniero de software que trabajaba en Facebook y que quería simplificar la forma de crear interfaces de usuario complejas.

\n

Es una biblioteca muy popular y es usada por muchas empresas como Facebook, Netflix, Airbnb, Twitter, Instagram, etc.

\n

Enlaces de interés:

\n\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/que-es-un-componente.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "que-es-un-componente", 3 | "level": 0, 4 | "title": "¿Qué es un componente?", 5 | "content": "

Un componente es una pieza de código que renderiza una parte de la interfaz. Los componentes pueden ser parametrizados, reutilizados y pueden contener su propio estado.

\n

En React los componentes se crean usando funciones o clases.

\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/que-hace-el-hook-use-layout-effect.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "que-hace-el-hook-use-layout-effect", 3 | "level": 1, 4 | "title": "¿Qué hace el hook `useLayoutEffect`?", 5 | "content": "

useLayoutEffect funciona igual que el hook useEffect, con la excepción de que este se dispara sincrónicamente después de leer todas las mutaciones del DOM.

\n

Llama useLayoutEffect en el nivel superior del componente.

\n
import { useLayoutEffect } from 'react';\n\nuseLayoutEffect(() => {\n  return () => {\n  }\n}, []);
\n\n

useLayoutEffect recibe dos argumentos:

\n
    \n
  • Una función callback que define el efecto.
  • \n
  • Una lista de dependencias.
  • \n
\n

Aunque el useEffect es el hook de renderizado más usado, si se necesita que los efectos del DOM muten cambiando la apariencia entre el efecto y el renderizado, entonces es conveniente que uses el useLayoutEffect.

\n
Orden de ejecución del useLayoutEffect
\n

El orden de ejecución del useLayoutEffect, ya que se ejecuta de forma síncrona, al momento en que React termina de ejecutar todas las mutaciones, pero antes de renderizarlo en pantalla, es el siguiente:

\n
    \n
  • El componente se actualiza por algún cambio de estado, props o el padre se re-renderiza
  • \n
  • React renderiza el componente
  • \n
  • Tu efecto es ejecutado
  • \n
  • La pantalla se actualiza “visualmente”
  • \n
\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/que-problemas-crees-que-pueden-aparecer-en-una-aplicacion-al-querer-visualizar-listas-de-miles-millones-de-datos.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "que-problemas-crees-que-pueden-aparecer-en-una-aplicacion-al-querer-visualizar-listas-de-miles-millones-de-datos", 3 | "title": "¿Qué problemas crees que pueden aparecer en una aplicación al querer visualizar listas de miles/millones de datos?", 4 | "content": "
    \n
  • Tiempo de respuesta del servidor: Hacer peticiones de millones de datos no es, en general, una buena estrategia. Incluso en el mejor de los casos, en el que el servidor solo debe devolver los datos sin tratarlos, hay un coste asociado al parseo y envío de los mismos a través de la red. Llamadas con un tamaño desmesurado pueden incurrir en interfaces lentas, e incluso en timeouts en la respuesta.
  • \n
  • Problemas de rendimiento: Aunque es cierto que React se basa en un modelo declarativo en el cual no debemos tener una exhaustivo control o gestión de cómo se renderiza, no hay que olvidar que malas decisiones técnicas pueden conllevar aplicaciones totalmente inestables incluso con las mejores tecnologías. No es viable renderizar un DOM con millones de elementos, el navegador no podrá gestionarlo y, tarde o temprano, la aplicación no será usable.
  • \n
\n

Como developers, nuestra misión es encontrar el equilibrio entre rendimiento y experiencia, intentando priorizar siempre cómo el usuario sentirá la aplicación. No hay ningún caso lo suficientemente justificado para renderizar en pantalla miles de datos.

\n

El espacio de visualización es limitado (viewport), al igual que deberían serlo los datos que añadimos al DOM.

\n
\n" 5 | } 6 | -------------------------------------------------------------------------------- /public/content/que-quiere-decir-warning-each-child-in-a-list-should-have-a-unique-key-prop.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "que-quiere-decir-warning-each-child-in-a-list-should-have-a-unique-key-prop", 3 | "level": -1, 4 | "title": "¿Qué quiere decir: Warning: Each child in a list should have a unique key prop?", 5 | "content": "

Es un error bastante común en React y que puede parecernos un poco extraño si estamos empezando a aprender esta tecnología. Por suerte, es bastante sencillo de solucionar.

\n

Básicamente, este mensaje aparece en la consola cuando estamos renderizando un listado dentro de nuestro componente, pero no le estamos indicando la propiedad "key". React usa esta propiedad para determinar qué elemento hijo dentro de un listado ha sufrido cambios, por lo que funciona como una especie de identificativo.

\n

De esta manera, React utiliza esta información para identificar las diferencias existentes con respecto al DOM y optimizar la renderización del listado, determinando qué elementos necesitan volverse a calcular. Esto habitualmente pasa cuando agregamos, eliminamos o cambiamos el orden de los items en una lista.

\n

Recomendamos revisar las siguientes secciones:

\n\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/que-significa-exactamente-que-sea-declarativo.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "que-significa-exactamente-que-sea-declarativo", 3 | "level": 0, 4 | "title": "¿Qué significa exactamente que sea declarativo?", 5 | "content": "

No le decimos cómo debe renderizar la interfaz a base de instrucciones. Le decimos qué debe renderizar y React se encarga de renderizarlo.

\n

Un ejemplo entre declarativo e imperativo:

\n
// Declarativo\nconst element = <h1>Hello, world</h1>\n\n// Imperativo\nconst element = document.createElement('h1')\nelement.innerHTML = 'Hello, world'
\n\n\n\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/que-solucion-es-implementarias-para-evitar-problemas-de-rendimiento-al-trabajar-con-listas-de-miles-millones-de-datos.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "que-solucion-es-implementarias-para-evitar-problemas-de-rendimiento-al-trabajar-con-listas-de-miles-millones-de-datos", 3 | "title": "¿Qué solución/es implementarías para evitar problemas de rendimiento al trabajar con listas de miles/millones de datos?", 4 | "content": "
Pagination
\n

En lugar de recibir la lista en una sola llamada a la API (lo cual sería negativo tanto para el rendimiento como para el propio servidor y tiempo de respuesta de la API), podríamos implementar un sistema de paginación en el cual la API recibirá un offset o rango de datos deseados. En el FE nuestra responsabilidad es mostrar unos controles adecuados (interfaz de paginación) y gestionar las llamadas a petición de cambio de página para siempre limitar la cantidad de DOM renderizado evitando así una sobrecarga del DOM y, por lo tanto, problemas de rendimiento.

\n
Virtualization
\n

Existe una técnica llamada Virtualización que gestiona cuántos elementos de una lista mantenemos vivos en el DOM. El concepto se basa en solo montar los elementos que estén dentro del viewport más un buffer determinado (para evitar falta de datos al hacer scroll) y, en cambio, desmontar del DOM todos aquellos elementos que estén fuera de la vista del usuario. De este modo podremos obtener lo mejor de los dos mundos, una experiencia integrada y un DOM liviano que evitará posibles errores de rendimiento. Con esta solución también podremos aprovechar que contamos con los datos en memoria para realizar búsquedas/filtrados sin necesidad de más llamadas al servidor.

\n

Puedes consultar esta librería para aplicar Virtualización con React: React Virtualized.

\n

Hay que tener en cuenta que cada caso de uso puede encontrar beneficios y/o perjuicios en ambos métodos, dependiendo de factores como capacidad de respuesta de la API, cantidad de datos, necesidad de filtros complejos, etc. Por ello es importante analizar cada caso con criterio.

\n
\n" 5 | } 6 | -------------------------------------------------------------------------------- /public/content/que-son-las-props-en-react.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "que-son-las-props-en-react", 3 | "level": 0, 4 | "title": "¿Qué son las props en React?", 5 | "content": "

Las props son las propiedades de un componente. Son datos que se pasan de un componente a otro. Por ejemplo, si tienes un componente Button que muestra un botón, puedes pasarle una prop text para que el botón muestre ese texto:

\n
function Button(props) {\n  return <button>{props.text}</button>\n}
\n\n

Podríamos entender que el componente Button es un botón genérico, y que la prop text es el texto que se muestra en el botón. Así estamos creando un componente reutilizable.

\n

Debe considerarse además que al usar cualquier expresión JavaScript dentro de JSX debe envolverlos con {}, en este caso el objeto props, de otra forma JSX lo considerará como texto plano.

\n

Para usarlo, indicamos el nombre del componente y le pasamos las props que queremos:

\n
<Button text=\"Haz clic aquí\" />\n<Button text=\"Seguir a @midudev\" />
\n\n

Las props son una forma de parametrizar nuestros componentes igual que hacemos con las funciones. Podemos pasarle cualquier tipo de dato a un componente, incluso otros componentes.

\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/que-son-las-refs-en-react.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "que-son-las-refs-en-react", 3 | "level": 1, 4 | "title": "¿Qué son las refs en React?", 5 | "content": "

Las refs nos permiten crear una referencia a un elemento del DOM o a un valor que se mantendrá entre renderizados. Se pueden declarar por medio del comando createRef o con el hook useRef.

\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/que-son-los-componentes-stateless.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "que-son-los-componentes-stateless", 3 | "level": 1, 4 | "title": "¿Qué son los componentes *stateless*?", 5 | "content": "

Los componentes stateless son componentes que no tienen estado. Estos componentes se crean con una function y no tienen acceso al estado de la aplicación. La ventaja que tienen estos componentes es que hace que sea más fácil crear componentes puros (que siempre renderizan lo mismo para unas mismas props).

\n
// Este es un ejemplo de componente stateless\nfunction Button({ text }) {\n  return (\n    <button>\n      {text}\n    </button>\n  )\n}
\n\n\n\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/que-son-los-high-order-components-hoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "que-son-los-high-order-components-hoc", 3 | "level": 1, 4 | "title": "¿Qué son los High Order Components (HOC)?", 5 | "content": "

Los High Order Components son funciones que reciben un componente como parámetro y devuelven un componente.

\n
function withLayout(Component) {\n  return function(props) {\n    return <main>\n      <section>\n        <Component {...props} />\n      </section>\n    </main>\n  }\n}
\n\n

En este caso, la función withLayout recibe un componente como parámetro y devuelve un componente. El componente devuelto renderiza el componente que se le pasa como parámetro dentro de un layout.

\n

Es un patrón que nos permite reutilizar código y así podemos inyectar funcionalidad, estilos o cualquier otra cosa a un componente de forma sencilla.

\n

Con la llegada de los hooks, los HOCs se han vuelto menos populares, pero todavía se usan en algunos casos.

\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/que-son-los-hooks.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "que-son-los-hooks", 3 | "level": 0, 4 | "title": "¿Qué son los hooks?", 5 | "content": "

Los Hooks son una API de React que nos permite tener estado, y otras características de React, en los componentes creados con una function.

\n

Esto, antes, no era posible y nos obligaba a crear un componente con class para poder acceder a todas las posibilidades de la librería.

\n

Hooks es gancho y, precisamente, lo que hacen, es que te permiten enganchar tus componentes funcionales a todas las características que ofrece React.

\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/que-son-los-portales-en-react.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "que-son-los-portales-en-react", 3 | "title": "¿Qué son los portales en React?", 4 | "content": "

Los portales nos permiten renderizar un componente en un nodo del DOM que no es hijo del componente que lo renderiza.

\n

Es perfecto para ciertos casos de uso como, por ejemplo, modales:

\n
import { createPortal } from 'react-dom'\n\nfunction Modal() {\n  return createPortal(\n    <div className=\"modal\">\n      <h1>Modal</h1>\n    </div>,\n    document.getElementById('modal')\n  )\n}
\n\n

createPortal acepta dos parámetros:

\n
    \n
  • El primer parámetro es el componente que queremos renderizar
  • \n
  • El segundo parámetro es el nodo del DOM donde queremos renderizar el componente
  • \n
\n

En este caso el modal se renderiza en el nodo #modal del DOM.

\n
\n" 5 | } 6 | -------------------------------------------------------------------------------- /public/content/que-son-mejores-los-componentes-de-clase-o-los-componentes-funcionales.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "que-son-mejores-los-componentes-de-clase-o-los-componentes-funcionales", 3 | "level": 1, 4 | "title": "¿Qué son mejores los componentes de clase o los componentes funcionales?", 5 | "content": "

Desde que en React 16.8.0 se incluyeron los hooks, los componentes de funciones pueden hacer casi todo lo que los componentes de clase.

\n

Aunque no hay una respuesta clara a esta pregunta, normalmente los componentes funcionales son más sencillos de leer y escribir y pueden tener un mejor rendimiento en general.

\n

Además, los hooks solo se pueden usar en los componentes funcionales. Esto es importante, ya que con la creación de custom hooks podemos reutilizar la lógica y podría simplificar nuestros componentes.

\n

Por otro lado, los componentes de clase nos permiten usar el ciclo de vida de los componentes, algo que no podemos hacer con los componentes funcionales donde solo podemos usar useEffect.

\n

Referencias:

\n\n
\n" 6 | } 7 | -------------------------------------------------------------------------------- /public/content/sun.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midudev/preguntas-entrevista-react/5b0737a8503b34046fc0cb0583a6b9b6eb4a2ba7/public/content/sun.png -------------------------------------------------------------------------------- /public/cual-es-la-diferencia-entre-componente-y-elemento-en-react.json: -------------------------------------------------------------------------------- 1 | {"id":"cual-es-la-diferencia-entre-componente-y-elemento-en-react","level":0,"title":"¿Cuál es la diferencia entre componente y elemento en React?","content":"

Un componente es una función o clase que recibe props y devuelve un elemento.\nUn elemento es un objeto que representa un nodo del DOM o una instancia de un componente de React.

\n
// Elemento que representa un nodo del DOM\n{\n  type: 'button',\n  props: {\n    className: 'button button-blue',\n    children: {\n      type: 'b',\n      props: {\n        children: 'OK!'\n      }\n    }\n  }\n}\n\n// Elemento que representa una instancia de un componente\n{\n  type: Button,\n  props: {\n    color: 'blue',\n    children: 'OK!'\n  }\n}
\n\n\n\n
\n"} 2 | -------------------------------------------------------------------------------- /public/cual-es-la-diferencia-entre-use-callback-y-use-memo.json: -------------------------------------------------------------------------------- 1 | {"id":"cual-es-la-diferencia-entre-use-callback-y-use-memo","level":1,"title":"¿Cuál es la diferencia entre `useCallback` y `useMemo`?","content":"

La diferencia entre useCallback y useMemo es que useCallback memoriza una función y useMemo memoriza el resultado de una función.

\n

En cualquier caso, en realidad, useCallback es una versión especializada de useMemo. De hecho se puede simular la funcionalidad de useCallback con useMemo:

\n
const memoizedCallback = useMemo(() => {\n  return () => {\n    doSomething(a, b)\n  }\n}, [a, b])
\n\n\n\n
\n"} 2 | -------------------------------------------------------------------------------- /public/cuales-son-las-caracteristicas-principales-de-react.json: -------------------------------------------------------------------------------- 1 | {"id":"cuales-son-las-caracteristicas-principales-de-react","level":0,"title":"¿Cuáles son las características principales de React?","content":"

Las características principales de React son:

\n
    \n
  • Componentes: React está basado en la componetización de la UI. La interfaz se divide en componentes independientes, que contienen su propio estado. Cuando el estado de un componente cambia, React vuelve a renderizar la interfaz.

    \n
  • \n
  • Virtual DOM: React usa un DOM virtual para renderizar los componentes. El DOM virtual es una representación en memoria del DOM real. Cuando el estado de un componente cambia, React vuelve a renderizar la interfaz. En lugar de modificar el DOM real, React modifica el DOM virtual y, a continuación, compara el DOM virtual con el DOM real. De esta forma, React sabe qué cambios se deben aplicar al DOM real.

    \n
  • \n
  • Declarativo: React es declarativo, lo que significa que no se especifica cómo se debe realizar una tarea, sino qué se debe realizar. Esto hace que el código sea más fácil de entender y de mantener.

    \n
  • \n
  • Unidireccional: React es unidireccional, lo que significa que los datos fluyen en una sola dirección. Los datos fluyen de los componentes padres a los componentes hijos.

    \n
  • \n
  • Universal: React se puede ejecutar tanto en el cliente como en el servidor. Además, puedes usar React Native para crear aplicaciones nativas para Android e iOS.

    \n
  • \n
\n
\n"} 2 | -------------------------------------------------------------------------------- /public/cuales-son-las-reglas-de-los-hooks-en-react.json: -------------------------------------------------------------------------------- 1 | {"id":"cuales-son-las-reglas-de-los-hooks-en-react","level":1,"title":"¿Cuáles son las reglas de los hooks en React?","content":"

Los hooks en React tienen dos reglas fundamentales:

\n
    \n
  • Los hooks solo se pueden usar en componentes funcionales o custom hooks.
  • \n
  • Los hooks solo se pueden llamar en el nivel superior de un componente. No se pueden llamar dentro de bucles, condicionales o funciones anidadas.
  • \n
\n
\n"} 2 | -------------------------------------------------------------------------------- /public/cuantos-use-effect-puede-tener-un-componente.json: -------------------------------------------------------------------------------- 1 | {"id":"cuantos-use-effect-puede-tener-un-componente","level":1,"title":"¿Cuántos `useEffect` puede tener un componente?","content":"

Aunque normalmente los componentes de React solo cuentan con un useEffect lo cierto es que podemos tener tantos useEffect como queramos en un componente. Cada uno de ellos se ejecutará cuando se renderice el componente o cuando cambien las dependencias del efecto.

\n
\n"} 2 | -------------------------------------------------------------------------------- /public/es-buena-idea-usar-siempre-use-callback-para-optimizar-nuestros-componentes.json: -------------------------------------------------------------------------------- 1 | {"id":"es-buena-idea-usar-siempre-use-callback-para-optimizar-nuestros-componentes","level":1,"title":"¿Es buena idea usar siempre `useCallback` para optimizar nuestros componentes?","content":"

No. useCallback es una herramienta que nos permite optimizar nuestros componentes, pero no es una herramienta mágica que nos va a hacer que nuestros componentes sean más rápidos. A veces la creación de una función es tan rápida que no merece la pena memorizarla. Incluso, en algunos casos, puede ser más lento memorizarla que crearla de nuevo.

\n
\n"} 2 | -------------------------------------------------------------------------------- /public/es-buena-idea-usar-siempre-use-memo-para-optimizar-nuestros-componentes.json: -------------------------------------------------------------------------------- 1 | {"id":"es-buena-idea-usar-siempre-use-memo-para-optimizar-nuestros-componentes","level":1,"title":"¿Es buena idea usar siempre `useMemo` para optimizar nuestros componentes?","content":"

No. useMemo es una herramienta que nos permite optimizar nuestros componentes, pero no es una herramienta mágica que nos va a hacer que nuestros componentes sean más rápidos. A veces el cálculo de un valor es tan rápido que no merece la pena memorizarlo. Incluso, en algunos casos, puede ser más lento memorizarlo que calcularlo de nuevo.

\n
\n"} 2 | -------------------------------------------------------------------------------- /public/es-react-una-biblioteca-o-un-framework-por-que.json: -------------------------------------------------------------------------------- 1 | {"id":"es-react-una-biblioteca-o-un-framework-por-que","title":"¿Es React una biblioteca o un framework? ¿Por qué?","content":"

Existe una fina línea hoy en día entre qué es una biblioteca o un framework. Oficialmente, React se autodenomina como biblioteca. Esto es porque para poder crear una aplicación completa, necesitas usar otras bibliotecas.

\n

Por ejemplo, React no ofrece un sistema de enrutado de aplicaciones oficial. Por ello, hay que usar una biblioteca como React Router o usar un framework como Next.js que ya incluye un sistema de enrutado.

\n

Tampoco puedes usar React para añadir las cabeceras que van en el <head> en tu aplicación, y también necesitarás otra biblioteca o framework para solucionar esto.

\n

Otra diferencia es que React no está opinionado sobre qué empaquetador de aplicaciones usar. En cambio Angular en su propio tutorial ya te indica que debes usar @angular/cli para crear una aplicación, en cambio React siempre te deja la libertad de elegir qué empaquetador usar y ofrece diferentes opciones.

\n

Aún así, existe gente que considera a React como un framework. Aunque no hay una definición oficial de qué es un framework, la mayoría de la gente considera que un framework es una biblioteca que incluye otras bibliotecas para crear una aplicación completa de forma opinionada y casi sin configuración.

\n

Por ejemplo, Next.js se podría considerar un framework de React porque incluye React, un sistema de enrutado, un sistema de renderizado del lado del servidor, etc.

\n
\n"} 2 | -------------------------------------------------------------------------------- /public/explica-casos-de-uso-del-hook-use-effect.json: -------------------------------------------------------------------------------- 1 | {"id":"explica-casos-de-uso-del-hook-use-effect","level":0,"title":"Explica casos de uso del hook `useEffect`","content":"

Podemos usar el hook useEffect de diferentes formas, tales como:

\n
    \n
  • Ejecutar código cuando se renderiza el componente, cuando cambian las dependencias del efecto o cuando se desmonta el componente.
  • \n
  • Por eso puede ser útil para hacer llamadas a APIs, ya que sea nada más montar el componente o cuando cambian las dependencias.
  • \n
  • Realizar tracking de eventos, como Google Analytics, para saber qué páginas visitan los usuarios.
  • \n
  • Podemos validar un formulario para que cada vez que cambie el estado, podamos actualizar la UI y mostrar dónde están los errores.
  • \n
  • Podemos suscribirnos a eventos del navegador, como por ejemplo el evento resize para saber cuando el usuario cambia el tamaño de la ventana.
  • \n
\n
\n"} 2 | -------------------------------------------------------------------------------- /public/favicon.dark.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midudev/preguntas-entrevista-react/5b0737a8503b34046fc0cb0583a6b9b6eb4a2ba7/public/favicon.dark.ico -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midudev/preguntas-entrevista-react/5b0737a8503b34046fc0cb0583a6b9b6eb4a2ba7/public/favicon.ico -------------------------------------------------------------------------------- /public/moon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midudev/preguntas-entrevista-react/5b0737a8503b34046fc0cb0583a6b9b6eb4a2ba7/public/moon.png -------------------------------------------------------------------------------- /public/og.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midudev/preguntas-entrevista-react/5b0737a8503b34046fc0cb0583a6b9b6eb4a2ba7/public/og.png -------------------------------------------------------------------------------- /public/por-que-debemos-utilizar-una-funcion-para-actualizar-el-estado-de-react.json: -------------------------------------------------------------------------------- 1 | {"id":"por-que-debemos-utilizar-una-funcion-para-actualizar-el-estado-de-react","level":1,"title":"¿Por qué debemos utilizar una función para actualizar el estado de React?","content":"

A la hora de actualizar el estado de React, debemos utilizar la función que nos facilita el hook useState para actualizar el estado.

\n
const [count, setCount] = useState(0)\n\nsetCount(count + 1)
\n\n

¿Por qué es esto necesario? En primer lugar, el estado en React debe ser inmutable. Es decir, no podemos modificar el estado directamente, sino que debemos siempre crear un nuevo valor para el nuevo estado.

\n

Esto nos permite que la integridad de la UI respecto a los datos que renderiza siempre es correcta.

\n

Por otro lado, llamar a una función le permite a React saber que el estado ha cambiado y que debe re-renderizar el componente si es necesario. Además esto lo hace de forma asíncrona, por lo que podemos llamar a setCount tantas veces como queramos y React se encargará de actualizar el estado cuando lo considere oportuno.

\n
\n"} 2 | -------------------------------------------------------------------------------- /public/por-que-es-recomendable-usar-fragment-en-vez-de-un-div.json: -------------------------------------------------------------------------------- 1 | {"id":"por-que-es-recomendable-usar-fragment-en-vez-de-un-div","level":0,"title":"¿Por qué es recomendable usar Fragment en vez de un div?","content":"

Las razones por las que es recomendable usar Fragment en vez de un div a la hora de envolver varios elementos son:

\n
    \n
  • Los div añaden un elemento extra al DOM, mientras que los Fragments no. Esto hace que el número de elementos HTML y la profundidad del DOM sea menor.
  • \n
  • Los elementos envueltos con Fragment son afectados directamente por las propiedades flex o grid de CSS de su elemento padre. Si usas un div es posible que tengas problemas con el alineamiento de los elementos.
  • \n
  • Los Fragments son más rápidos que los div ya que no tienen que ser renderizados.
  • \n
  • Los div aplican CSS por defecto (hace que lo que envuelve el div se comporte como un bloque al aplicar un display: block) mientras que los Fragment no aplican ningún estilo por defecto.
  • \n
\n
\n"} 2 | -------------------------------------------------------------------------------- /public/por-que-puede-ser-mala-idea-pasar-siempre-todas-las-props-de-un-objeto-a-un-componente.json: -------------------------------------------------------------------------------- 1 | {"id":"por-que-puede-ser-mala-idea-pasar-siempre-todas-las-props-de-un-objeto-a-un-componente","level":1,"title":"¿Por qué puede ser mala idea pasar siempre todas las props de un objeto a un componente?","content":"

Digamos que tenemos un componente App que recibe un objeto props con todas las props que necesita:

\n
function App(props) {\n  return <h1>{props.title}</h1>\n}
\n\n

Y que tenemos otro componente Layout que recibe un objeto props con todas las props que necesita:

\n
function Layout(props) {\n  return (\n    <div>\n      <App {...props} />\n    </div>\n  )\n}
\n\n

En este caso, Layout está pasando todas las props que recibe a App. Esto puede ser una mala idea por varias razones:

\n
    \n
  • Si Layout recibe una prop que no necesita, la pasará a App y éste puede que no la use. Esto puede ser confuso para el que lea el código.
  • \n
\n
\n"} 2 | -------------------------------------------------------------------------------- /public/por-que-strict-mode-renderiza-dos-veces-la-aplicacion.json: -------------------------------------------------------------------------------- 1 | {"id":"por-que-strict-mode-renderiza-dos-veces-la-aplicacion","title":"¿Por qué `StrictMode` renderiza dos veces la aplicación?","content":"

Cuando el modo StrictMode está activado, React monta los componentes dos veces (el estado y el DOM se preserva). Esto ayuda a encontrar efectos que necesitan una limpieza o expone problemas con race conditions.

\n
\n"} 2 | -------------------------------------------------------------------------------- /public/que-diferencia-existe-entre-shadow-dom-y-virtual-dom.json: -------------------------------------------------------------------------------- 1 | {"id":"que-diferencia-existe-entre-shadow-dom-y-virtual-dom","level":-1,"title":"¿Qué diferencia existe entre Shadow DOM y Virtual DOM?","content":"

El Shadow DOM es una API del navegador que nos permite crear un árbol de nodos DOM independiente dentro de un elemento del DOM. Esto nos permite crear componentes que no interfieran con el resto de la aplicación. Se usa especialmente con Web Components.

\n

El Virtual DOM es una representación del DOM en memoria. Esta representación se crea cada vez que se produce un cambio en el DOM. Esto nos permite comparar el DOM actual con el DOM anterior y así determinar qué cambios se deben realizar en el DOM real. Lo usa React y otras bibliotecas para hacer el mínimo número de cambios en el DOM real.

\n
\n"} 2 | -------------------------------------------------------------------------------- /public/que-diferencia-hay-entre-props-y-state.json: -------------------------------------------------------------------------------- 1 | {"id":"que-diferencia-hay-entre-props-y-state","level":0,"title":"¿Qué diferencia hay entre props y state?","content":"

Las props son un objeto que se pasan como argumentos de un componente padre a un componente hijo. Son inmutables y no se pueden modificar desde el componente hijo.

\n

El state es un valor que se define dentro de un componente. Su valor es inmutable (no se puede modificar directamente) pero se puede establecer un valor nuevo del estado para que React vuelva a renderizar el componente.

\n

Así que mientras tanto props como state afectan al renderizado del componente, su gestión es diferente.

\n
\n"} 2 | -------------------------------------------------------------------------------- /public/que-diferencia-hay-entre-render-to-static-node-stream-y-render-to-pipeable-stream.json: -------------------------------------------------------------------------------- 1 | {"id":"que-diferencia-hay-entre-render-to-static-node-stream-y-render-to-pipeable-stream","title":"¿Qué diferencia hay entre `renderToStaticNodeStream()` y `renderToPipeableStream()`?","content":"

renderToStaticNodeStream() devuelve un stream de nodos estáticos, esto significa que no añade atributos extras para el DOM que React usa internamente para poder lograr la hidratación del HTML en el cliente. Esto significa que no podrás hacer el HTML interactivo en el cliente, pero puede ser útil para páginas totalmente estáticas.

\n

renderToPipeableStream() devuelve un stream de nodos que contienen atributos del DOM extra para que React pueda hidratar el HTML en el cliente. Esto significa que podrás hacer el HTML interactivo en el cliente pero puede ser más lento que renderToStaticNodeStream().

\n
\n"} 2 | -------------------------------------------------------------------------------- /public/que-diferencia-hay-entre-use-effect-y-use-layout-effect.json: -------------------------------------------------------------------------------- 1 | {"id":"que-diferencia-hay-entre-use-effect-y-use-layout-effect","level":1,"title":"¿Qué diferencia hay entre `useEffect` y `useLayoutEffect`?","content":"

Aunque ambos son muy parecidos, tienen una pequeña diferencia en el momento en el que se ejecutan.

\n

useLayoutEffect se ejecuta de forma síncrona inmediatamente después que React haya actualizado completamente el DOM tras el renderizado. Puede ser útil si necesitas recuperar un elemento del DOM y acceder a sus dimensiones o posición en pantalla.

\n

useEffect se ejecuta de forma asíncrona tras el renderizado, pero no asegura que el DOM se haya actualizado. Es decir, si necesitas recuperar un elemento del DOM y acceder a sus dimensiones o posición en pantalla, no podrás hacerlo con useEffect porque no tienes la garantía de que el DOM se haya actualizado.

\n

Normalmente, el 99% de las veces, vas a querer utilizar useEffect y, además, tiene mejor rendimiento, ya que no bloquea el renderizado.

\n
\n"} 2 | -------------------------------------------------------------------------------- /public/que-es-el-ciclo-de-vida-de-un-componente-en-react.json: -------------------------------------------------------------------------------- 1 | {"id":"que-es-el-ciclo-de-vida-de-un-componente-en-react","level":1,"title":"¿Qué es el ciclo de vida de un componente en React?","content":"

En los componentes de clase, el ciclo de vida de un componente se divide en tres fases:

\n
    \n
  • Montaje: cuando el componente se añade al DOM.
  • \n
  • Actualización: cuando el componente se actualiza.
  • \n
  • Desmontaje: cuando el componente se elimina del DOM.
  • \n
\n

Dentro de este ciclo de vida, existe un conjunto de métodos que se ejecutan en el componente.

\n

Estos métodos se definen en la clase y se ejecutan en el orden que se muestran a continuación:

\n
    \n
  • constructor
  • \n
  • render
  • \n
  • componentDidMount
  • \n
  • componentDidUpdate
  • \n
  • componentWillUnmount
  • \n
\n

En cada uno de estos métodos podemos ejecutar código que nos permita controlar el comportamiento de nuestro componente.

\n
\n"} 2 | -------------------------------------------------------------------------------- /public/que-es-el-hook-use-debug-value.json: -------------------------------------------------------------------------------- 1 | {"id":"que-es-el-hook-use-debug-value","title":"¿Qué es el hook `useDebugValue`?","content":"

Nos permite mostrar un valor personalizado en la pestaña de React DevTools que nos permitirá depurar nuestro código.

\n
import { useDebugValue } from 'react'\n\nfunction useCustomHook() {\n  const value = 'custom value'\n  useDebugValue(value)\n  return value\n}
\n\n

En este ejemplo, el valor personalizado que se muestra en la pestaña de React DevTools es custom value.

\n

Aunque es útil para depurar, no se recomienda usar este hook en producción.

\n
\n"} 2 | -------------------------------------------------------------------------------- /public/que-es-el-renderizado-condicional-en-react.json: -------------------------------------------------------------------------------- 1 | {"id":"que-es-el-renderizado-condicional-en-react","level":0,"title":"¿Qué es el renderizado condicional en React?","content":"

El renderizado condicional es la forma de mostrar un componente u otro dependiendo de una condición.

\n

Para hacer renderizado condicional en React usamos el operador ternario:

\n
function Button({ text }) {\n  return text ? <button>{text}</button> : null\n}
\n\n

En este caso, si la prop text existe, se renderiza el botón. Si no existe, no se renderiza nada.

\n

Es común encontrar implementaciones del renderizado condicional con el operador &&, del tipo:

\n
function List({ listArray }) {\n  return listArray?.length && listArray.map(item => item)\n}
\n\n

Parece que tiene sentido... si el length es positivo (mayor a cero) pintamos el map. !Pues no! ❌ Cuidado, si tiene length de cero ya que se pintará en el navegador un 0.

\n

Es preferible utilizar el operador ternario. Kent C. Dodds tiene un artículo interesante hablando del tema. Use ternaries rather than && in JSX

\n
\n"} 2 | -------------------------------------------------------------------------------- /public/que-es-el-server-side-rendering-y-que-ventajas-tiene.json: -------------------------------------------------------------------------------- 1 | {"id":"que-es-el-server-side-rendering-y-que-ventajas-tiene","level":1,"title":"¿Qué es el Server Side Rendering y qué ventajas tiene?","content":"

El Server Side Rendering es una técnica que consiste en renderizar el HTML en el servidor y enviarlo al cliente. Esto nos permite que el usuario vea la interfaz de la aplicación antes de que se cargue el JavaScript.

\n

Esta técnica nos permite mejorar la experiencia de usuario y mejorar el SEO de nuestra aplicación.

\n
\n"} 2 | -------------------------------------------------------------------------------- /public/que-es-el-strict-mode-en-react.json: -------------------------------------------------------------------------------- 1 | {"id":"que-es-el-strict-mode-en-react","level":1,"title":"¿Qué es el `StrictMode` en React?","content":"

El StrictMode es un componente que nos permite activar algunas comprobaciones de desarrollo en React. Por ejemplo, detecta componentes que se renderizan de forma innecesaria o funcionalidades obsoletas que se están usando.

\n
import { StrictMode } from 'react'\n\nfunction App() {\n  return (\n    <StrictMode>\n      <Component />\n    </StrictMode>\n  )\n}
\n\n\n\n
\n"} 2 | -------------------------------------------------------------------------------- /public/que-es-el-synthetic-event-en-react.json: -------------------------------------------------------------------------------- 1 | {"id":"que-es-el-synthetic-event-en-react","level":1,"title":"¿Qué es el `SyntheticEvent` en React?","content":"

El SyntheticEvent es una abstracción del evento nativo del navegador. Esto le permite a React tener un comportamiento consistente en todos los navegadores.

\n

Dentro del SyntheticEvent puede encontrarse una referencia al evento nativo en su atributo nativeEvent

\n
function App() {\n  function handleClick(event) {\n    console.log(event)\n  }\n\n  return <button onClick={handleClick}>Haz clic aquí</button>\n}
\n\n\n\n
\n"} 2 | -------------------------------------------------------------------------------- /public/que-es-flux.json: -------------------------------------------------------------------------------- 1 | {"id":"que-es-flux","level":-1,"title":"¿Qué es Flux?","content":"

Flux es un patrón de arquitectura de aplicaciones que se basa en un unidireccional de datos. En este patrón, los datos fluyen en una sola dirección: de las vistas a los stores.

\n

No es específico de React y se puede usar con cualquier librería de vistas. En este patrón, los stores son los encargados de almacenar los datos de la aplicación. Los stores emiten eventos cuando los datos cambian. Las vistas se suscriben a estos eventos para actualizar los datos.

\n

Esta arquitectura fue creada por Facebook para manejar la complejidad de sus aplicaciones. Redux se basó en este patrón para crear una biblioteca de gestión de estado global.

\n
\n"} 2 | -------------------------------------------------------------------------------- /public/que-es-jsx.json: -------------------------------------------------------------------------------- 1 | {"id":"que-es-jsx","level":0,"title":"¿Qué es JSX?","content":"

React usa JSX para declarar qué debe renderizar. JSX es una extensión de JavaScript que permite escribir un código más cercano visualmente a HTML, que mejora la legibilidad del código y hace que sea más fácil de entender.

\n

Sin JSX, deberíamos usar React.createElement para crear los elementos de la interfaz manualmente de esta forma:

\n
import { createElement } from 'react'\n\nfunction Hello() {\n  // un componente es una función! 👀\n  return React.createElement(\n    'h1', // elemento a renderizar\n    null, // atributos del elemento\n    'Hola Mundo 👋🌍!' // contenido del elemento\n  )\n}
\n\n

Esto es muy tedioso y poco legible. Por eso, React usa JSX para declarar qué debe renderizar. Por eso usamos JSX de esta forma:

\n
function Hello() {\n  return <h1>Hola Mundo 👋🌍!</h1>\n}
\n\n

Ambos códigos son equivalentes.

\n
\n"} 2 | -------------------------------------------------------------------------------- /public/que-es-la-hidratacion-hydration-en-react.json: -------------------------------------------------------------------------------- 1 | {"id":"que-es-la-hidratacion-hydration-en-react","level":1,"title":"¿Qué es la hidratación (hydration) en React?","content":"

Cuando renderizamos nuestra aplicación en el servidor, React genera un HTML estático. Este HTML estático es simplemente un string que contiene el HTML que se va a mostrar en la página.

\n

Cuando el navegador recibe el HTML estático, lo renderiza en la página. Sin embargo, este HTML estático no tiene interactividad. No tiene eventos, no tiene lógica, no tiene estado, etc. Podríamos decir que no tiene vida.

\n

Para hacer que este HTML estático pueda ser interactivo, React necesita que el HTML estático se convierta en un árbol de componentes de React. Esto se llama hidratación.

\n

De esta forma, en el cliente, React reutiliza este HTML estático y se dedica a adjuntar los eventos a los elementos, ejecutar los efectos que tengamos en los componentes y conciliar el estado de los componentes.

\n
\n"} 2 | -------------------------------------------------------------------------------- /public/que-es-react-dom.json: -------------------------------------------------------------------------------- 1 | {"id":"que-es-react-dom","level":0,"title":"¿Qué es React DOM?","content":"

React DOM es la librería que se encarga de renderizar los componentes de React para el navegador. Hay que tener en cuenta que React es una biblioteca que se puede usar en diferentes entornos (dispositivos móviles, apps de escritorio, terminal...).

\n

Mientras que la biblioteca de React, a secas, es el motor de creación de componentes, hooks, sistema de props y estado... React DOM es la librería que se encarga de renderizar los componentes de React específicamente en el navegador.

\n

React Native, por ejemplo, haría lo mismo, pero para dispositivos móviles.

\n"} 2 | -------------------------------------------------------------------------------- /public/que-es-react.json: -------------------------------------------------------------------------------- 1 | {"id":"que-es-react","level":0,"title":"¿Qué es React?","content":"

¿Qué es React?

\n

React es una biblioteca de JavaScript de código abierto para construir interfaces de usuario. Está basada en la componetización de la UI: la interfaz se divide en componentes independientes, que contienen su propio estado. Cuando el estado de un componente cambia, React vuelve a renderizar la interfaz.

\n

Esto hace que React sea una herramienta muy útil para construir interfaces complejas, ya que permite dividir la interfaz en piezas más pequeñas y reutilizables.

\n

Fue creada en 2011 por Jordan Walke, un ingeniero de software que trabajaba en Facebook y que quería simplificar la forma de crear interfaces de usuario complejas.

\n

Es una biblioteca muy popular y es usada por muchas empresas como Facebook, Netflix, Airbnb, Twitter, Instagram, etc.

\n

Enlaces de interés:

\n\n
\n"} 2 | -------------------------------------------------------------------------------- /public/que-es-un-componente.json: -------------------------------------------------------------------------------- 1 | {"id":"que-es-un-componente","level":0,"title":"¿Qué es un componente?","content":"

Un componente es una pieza de código que renderiza una parte de la interfaz. Los componentes pueden ser parametrizados, reutilizados y pueden contener su propio estado.

\n

En React los componentes se crean usando funciones o clases.

\n
\n"} 2 | -------------------------------------------------------------------------------- /public/que-hace-el-hook-use-layout-effect.json: -------------------------------------------------------------------------------- 1 | {"id":"que-hace-el-hook-use-layout-effect","level":1,"title":"¿Qué hace el hook `useLayoutEffect`?","content":"

useLayoutEffect funciona igual que el hook useEffect, con la excepción de que este se dispara sincrónicamente después de leer todas las mutaciones del DOM.

\n

Llama useLayoutEffect en el nivel superior del componente.

\n
import { useLayoutEffect } from 'react'\n\nuseLayoutEffect(() => {\n  return () => {}\n}, [])
\n\n

useLayoutEffect recibe dos argumentos:

\n
    \n
  • Una función callback que define el efecto.
  • \n
  • Una lista de dependencias.
  • \n
\n

Aunque el useEffect es el hook de renderizado más usado, si se necesita que los efectos del DOM muten cambiando la apariencia entre el efecto y el renderizado, entonces es conveniente que uses el useLayoutEffect.

\n
Orden de ejecución del useLayoutEffect
\n

El orden de ejecución del useLayoutEffect, ya que se ejecuta de forma síncrona, al momento en que React termina de ejecutar todas las mutaciones, pero antes de renderizarlo en pantalla, es el siguiente:

\n
    \n
  • El componente se actualiza por algún cambio de estado, props o el padre se re-renderiza
  • \n
  • React renderiza el componente
  • \n
  • Tu efecto es ejecutado
  • \n
  • La pantalla se actualiza “visualmente”
  • \n
\n
\n"} 2 | -------------------------------------------------------------------------------- /public/que-problemas-crees-que-pueden-aparecer-en-una-aplicacion-al-querer-visualizar-listas-de-miles-millones-de-datos.json: -------------------------------------------------------------------------------- 1 | {"id":"que-problemas-crees-que-pueden-aparecer-en-una-aplicacion-al-querer-visualizar-listas-de-miles-millones-de-datos","title":"¿Qué problemas crees que pueden aparecer en una aplicación al querer visualizar listas de miles/millones de datos?","content":"
    \n
  • Tiempo de respuesta del servidor: Hacer peticiones de millones de datos no es, en general, una buena estrategia. Incluso en el mejor de los casos, en el que el servidor solo debe devolver los datos sin tratarlos, hay un coste asociado al parseo y envío de los mismos a través de la red. Llamadas con un tamaño desmesurado pueden incurrir en interfaces lentas, e incluso en timeouts en la respuesta.
  • \n
  • Problemas de rendimiento: Aunque es cierto que React se basa en un modelo declarativo en el cual no debemos tener una exhaustivo control o gestión de cómo se renderiza, no hay que olvidar que malas decisiones técnicas pueden conllevar aplicaciones totalmente inestables incluso con las mejores tecnologías. No es viable renderizar un DOM con millones de elementos, el navegador no podrá gestionarlo y, tarde o temprano, la aplicación no será usable.
  • \n
\n

Como developers, nuestra misión es encontrar el equilibrio entre rendimiento y experiencia, intentando priorizar siempre cómo el usuario sentirá la aplicación. No hay ningún caso lo suficientemente justificado para renderizar en pantalla miles de datos.

\n

El espacio de visualización es limitado (viewport), al igual que deberían serlo los datos que añadimos al DOM.

\n
\n"} 2 | -------------------------------------------------------------------------------- /public/que-quiere-decir-warning-each-child-in-a-list-should-have-a-unique-key-prop.json: -------------------------------------------------------------------------------- 1 | {"id":"que-quiere-decir-warning-each-child-in-a-list-should-have-a-unique-key-prop","level":-1,"title":"¿Qué quiere decir: Warning: Each child in a list should have a unique key prop?","content":"

Es un error bastante común en React y que puede parecernos un poco extraño si estamos empezando a aprender esta tecnología. Por suerte, es bastante sencillo de solucionar.

\n

Básicamente, este mensaje aparece en la consola cuando estamos renderizando un listado dentro de nuestro componente, pero no le estamos indicando la propiedad "key". React usa esta propiedad para determinar qué elemento hijo dentro de un listado ha sufrido cambios, por lo que funciona como una especie de identificativo.

\n

De esta manera, React utiliza esta información para identificar las diferencias existentes con respecto al DOM y optimizar la renderización del listado, determinando qué elementos necesitan volverse a calcular. Esto habitualmente pasa cuando agregamos, eliminamos o cambiamos el orden de los items en una lista.

\n

Recomendamos revisar las siguientes secciones:

\n\n
\n"} 2 | -------------------------------------------------------------------------------- /public/que-significa-exactamente-que-sea-declarativo.json: -------------------------------------------------------------------------------- 1 | {"id":"que-significa-exactamente-que-sea-declarativo","level":0,"title":"¿Qué significa exactamente que sea declarativo?","content":"

No le decimos cómo debe renderizar la interfaz a base de instrucciones. Le decimos qué debe renderizar y React se encarga de renderizarlo.

\n

Un ejemplo entre declarativo e imperativo:

\n
// Declarativo\nconst element = <h1>Hello, world</h1>\n\n// Imperativo\nconst element = document.createElement('h1')\nelement.innerHTML = 'Hello, world'
\n\n\n\n
\n"} 2 | -------------------------------------------------------------------------------- /public/que-solucion-es-implementarias-para-evitar-problemas-de-rendimiento-al-trabajar-con-listas-de-miles-millones-de-datos.json: -------------------------------------------------------------------------------- 1 | {"id":"que-solucion-es-implementarias-para-evitar-problemas-de-rendimiento-al-trabajar-con-listas-de-miles-millones-de-datos","title":"¿Qué solución/es implementarías para evitar problemas de rendimiento al trabajar con listas de miles/millones de datos?","content":"
Pagination
\n

En lugar de recibir la lista en una sola llamada a la API (lo cual sería negativo tanto para el rendimiento como para el propio servidor y tiempo de respuesta de la API), podríamos implementar un sistema de paginación en el cual la API recibirá un offset o rango de datos deseados. En el FE nuestra responsabilidad es mostrar unos controles adecuados (interfaz de paginación) y gestionar las llamadas a petición de cambio de página para siempre limitar la cantidad de DOM renderizado evitando así una sobrecarga del DOM y, por lo tanto, problemas de rendimiento.

\n
Virtualization
\n

Existe una técnica llamada Virtualización que gestiona cuántos elementos de una lista mantenemos vivos en el DOM. El concepto se basa en solo montar los elementos que estén dentro del viewport más un buffer determinado (para evitar falta de datos al hacer scroll) y, en cambio, desmontar del DOM todos aquellos elementos que estén fuera de la vista del usuario. De este modo podremos obtener lo mejor de los dos mundos, una experiencia integrada y un DOM liviano que evitará posibles errores de rendimiento. Con esta solución también podremos aprovechar que contamos con los datos en memoria para realizar búsquedas/filtrados sin necesidad de más llamadas al servidor.

\n

Puedes consultar esta librería para aplicar Virtualización con React: React Virtualized.

\n

Hay que tener en cuenta que cada caso de uso puede encontrar beneficios y/o perjuicios en ambos métodos, dependiendo de factores como capacidad de respuesta de la API, cantidad de datos, necesidad de filtros complejos, etc. Por ello es importante analizar cada caso con criterio.

\n
\n"} 2 | -------------------------------------------------------------------------------- /public/que-son-las-props-en-react.json: -------------------------------------------------------------------------------- 1 | {"id":"que-son-las-props-en-react","level":0,"title":"¿Qué son las props en React?","content":"

Las props son las propiedades de un componente. Son datos que se pasan de un componente a otro. Por ejemplo, si tienes un componente Button que muestra un botón, puedes pasarle una prop text para que el botón muestre ese texto:

\n
function Button(props) {\n  return <button>{props.text}</button>\n}
\n\n

Podríamos entender que el componente Button es un botón genérico, y que la prop text es el texto que se muestra en el botón. Así estamos creando un componente reutilizable.

\n

Debe considerarse además que al usar cualquier expresión JavaScript dentro de JSX debe envolverlos con {}, en este caso el objeto props, de otra forma JSX lo considerará como texto plano.

\n

Para usarlo, indicamos el nombre del componente y le pasamos las props que queremos:

\n
<Button text=\"Haz clic aquí\" />\n<Button text=\"Seguir a @midudev\" />
\n\n

Las props son una forma de parametrizar nuestros componentes igual que hacemos con las funciones. Podemos pasarle cualquier tipo de dato a un componente, incluso otros componentes.

\n
\n"} 2 | -------------------------------------------------------------------------------- /public/que-son-las-refs-en-react.json: -------------------------------------------------------------------------------- 1 | {"id":"que-son-las-refs-en-react","level":1,"title":"¿Qué son las refs en React?","content":"

Las refs nos permiten crear una referencia a un elemento del DOM o a un valor que se mantendrá entre renderizados. Se pueden declarar por medio del comando createRef o con el hook useRef.

\n
\n"} 2 | -------------------------------------------------------------------------------- /public/que-son-los-componentes-stateless.json: -------------------------------------------------------------------------------- 1 | {"id":"que-son-los-componentes-stateless","level":1,"title":"¿Qué son los componentes _stateless_?","content":"

Los componentes stateless son componentes que no tienen estado. Estos componentes se crean con una function y no tienen acceso al estado de la aplicación. La ventaja que tienen estos componentes es que hace que sea más fácil crear componentes puros (que siempre renderizan lo mismo para unas mismas props).

\n
// Este es un ejemplo de componente stateless\nfunction Button({ text }) {\n  return <button>{text}</button>\n}
\n\n\n\n
\n"} 2 | -------------------------------------------------------------------------------- /public/que-son-los-high-order-components-hoc.json: -------------------------------------------------------------------------------- 1 | {"id":"que-son-los-high-order-components-hoc","level":1,"title":"¿Qué son los High Order Components (HOC)?","content":"

Los High Order Components son funciones que reciben un componente como parámetro y devuelven un componente.

\n
function withLayout(Component) {\n  return function (props) {\n    return (\n      <main>\n        <section>\n          <Component {...props} />\n        </section>\n      </main>\n    )\n  }\n}
\n\n

En este caso, la función withLayout recibe un componente como parámetro y devuelve un componente. El componente devuelto renderiza el componente que se le pasa como parámetro dentro de un layout.

\n

Es un patrón que nos permite reutilizar código y así podemos inyectar funcionalidad, estilos o cualquier otra cosa a un componente de forma sencilla.

\n

Con la llegada de los hooks, los HOCs se han vuelto menos populares, pero todavía se usan en algunos casos.

\n
\n"} 2 | -------------------------------------------------------------------------------- /public/que-son-los-hooks.json: -------------------------------------------------------------------------------- 1 | {"id":"que-son-los-hooks","level":0,"title":"¿Qué son los hooks?","content":"

Los Hooks son una API de React que nos permite tener estado, y otras características de React, en los componentes creados con una function.

\n

Esto, antes, no era posible y nos obligaba a crear un componente con class para poder acceder a todas las posibilidades de la librería.

\n

Hooks es gancho y, precisamente, lo que hacen, es que te permiten enganchar tus componentes funcionales a todas las características que ofrece React.

\n
\n"} 2 | -------------------------------------------------------------------------------- /public/que-son-los-portales-en-react.json: -------------------------------------------------------------------------------- 1 | {"id":"que-son-los-portales-en-react","title":"¿Qué son los portales en React?","content":"

Los portales nos permiten renderizar un componente en un nodo del DOM que no es hijo del componente que lo renderiza.

\n

Es perfecto para ciertos casos de uso como, por ejemplo, modales:

\n
import { createPortal } from 'react-dom'\n\nfunction Modal() {\n  return createPortal(\n    <div className='modal'>\n      <h1>Modal</h1>\n    </div>,\n    document.getElementById('modal')\n  )\n}
\n\n

createPortal acepta dos parámetros:

\n
    \n
  • El primer parámetro es el componente que queremos renderizar
  • \n
  • El segundo parámetro es el nodo del DOM donde queremos renderizar el componente
  • \n
\n

En este caso el modal se renderiza en el nodo #modal del DOM.

\n
\n"} 2 | -------------------------------------------------------------------------------- /public/que-son-mejores-los-componentes-de-clase-o-los-componentes-funcionales.json: -------------------------------------------------------------------------------- 1 | {"id":"que-son-mejores-los-componentes-de-clase-o-los-componentes-funcionales","level":1,"title":"¿Qué son mejores los componentes de clase o los componentes funcionales?","content":"

Desde que en React 16.8.0 se incluyeron los hooks, los componentes de funciones pueden hacer casi todo lo que los componentes de clase.

\n

Aunque no hay una respuesta clara a esta pregunta, normalmente los componentes funcionales son más sencillos de leer y escribir y pueden tener un mejor rendimiento en general.

\n

Además, los hooks solo se pueden usar en los componentes funcionales. Esto es importante, ya que con la creación de custom hooks podemos reutilizar la lógica y podría simplificar nuestros componentes.

\n

Por otro lado, los componentes de clase nos permiten usar el ciclo de vida de los componentes, algo que no podemos hacer con los componentes funcionales donde solo podemos usar useEffect.

\n

Referencias:

\n\n
\n"} 2 | -------------------------------------------------------------------------------- /public/react.svg: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: Googlebot 2 | Disallow: 3 | 4 | User-agent: Googlebot-image 5 | Disallow: -------------------------------------------------------------------------------- /public/sun.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/midudev/preguntas-entrevista-react/5b0737a8503b34046fc0cb0583a6b9b6eb4a2ba7/public/sun.png -------------------------------------------------------------------------------- /pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## Descripción 2 | 3 | Por favor incluye una descripción breve de tus cambios 4 | 5 | ## Checklist 6 | 7 | - [ ] He revisado que mi pregunta no está duplicada 8 | - [ ] He revisado que la gramática de mis cambios es correcta 9 | - [ ] He agregado un link de (`**[⬆ Volver a índice](#índice)**`) y una línea separadora (`---`) al final de mi pregunta 10 | -------------------------------------------------------------------------------- /scripts/lint.mjs: -------------------------------------------------------------------------------- 1 | import markdownlint from 'markdownlint' 2 | 3 | const { readConfigSync } = markdownlint 4 | 5 | const options = { 6 | config: readConfigSync('.markdownlint.json'), 7 | files: ['README.md'], 8 | } 9 | 10 | markdownlint(options, function callback(err, result) { 11 | if (!err) { 12 | console.log(result.toString()) 13 | } 14 | }) 15 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | darkMode: 'class', 4 | content: ['./app/**/*.{js,ts,jsx,tsx}', './app/*.{js,ts,jsx,tsx}'], 5 | theme: { 6 | extend: { 7 | colors: { 8 | primary: '#000000', 9 | secondry: '#121212', 10 | }, 11 | backgroundImage: { 12 | 'blue-gradient-radial': 13 | 'radial-gradient(circle,#0141ff 0,rgba(161,252,70,0) 71%)', 14 | }, 15 | fontFamily: { 16 | grotesk: ['Space Grotesk', 'sans-serif'], 17 | }, 18 | boxShadow: { 19 | box: '0 0 0 1px rgb(0 0 0 / 7%), 0 2px 4px rgb(0 0 0 / 5%), 0 12px 24px rgb(0 0 0 / 5%)', 20 | darkbox: 21 | '0 0 0 1px rgb(255 255 255 / 7%), 0 2px 4px rgb(255 255 255 / 5%), 0 12px 24px rgb(255 255 255 / 5%)', 22 | }, 23 | }, 24 | }, 25 | plugins: [], 26 | } 27 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": false, 8 | "forceConsistentCasingInFileNames": true, 9 | "noEmit": true, 10 | "incremental": true, 11 | "esModuleInterop": true, 12 | "module": "esnext", 13 | "moduleResolution": "node", 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "jsx": "preserve", 17 | "plugins": [ 18 | { 19 | "name": "next" 20 | } 21 | ], 22 | "strictNullChecks": true 23 | }, 24 | "include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"], 25 | "exclude": ["node_modules"] 26 | } 27 | -------------------------------------------------------------------------------- /utils/posts.js: -------------------------------------------------------------------------------- 1 | import posts from '../public/content/index.json' 2 | 3 | export const readIndex = async () => { 4 | return posts 5 | } 6 | 7 | export const fetchPost = async slug => { 8 | const posts = await readIndex() 9 | 10 | const post = await import(`../public/content/${slug}.json`) 11 | console.log(post) 12 | const { content, level, title, id } = post 13 | 14 | const currentIndex = posts.findIndex(post => post.id === id) 15 | const prev = currentIndex > 0 ? posts[currentIndex - 1] : null 16 | const next = currentIndex < posts.length ? posts[currentIndex + 1] : null 17 | 18 | return { content, level, title, prev, next } 19 | } 20 | 21 | export const listPosts = async () => { 22 | const posts = await readIndex() 23 | return posts.map(post => ({ post: post.id })) 24 | } 25 | --------------------------------------------------------------------------------