Preguntas esenciales de JavaScript, React, TypeScript y CSS
Al aprender desarrollo web surgen preguntas que conectan el comportamiento de JavaScript con la construcción de interfaces y los estilos. Esta guía reúne conceptos frecuentes, compara herramientas y termina con un ejercicio de tarjetas en React y TypeScript.
JavaScript
1. ¿Cuál es el resultado de undefined === null?
El resultado es false. El operador estricto === compara el valor y el tipo sin convertir uno en otro. Aunque ambos valores representan una ausencia, undefined suele indicar que un dato no fue asignado, mientras que null expresa una ausencia intencional.
console.log(undefined === null); // false
2. ¿Cuáles son los tipos primitivos?
JavaScript tiene siete tipos primitivos:
| Tipo | Ejemplo | Uso |
|---|---|---|
string | 'Hola' | Texto |
number | 25 o 3.14 | Números, incluidos enteros y decimales |
bigint | 123n | Enteros fuera del rango seguro de number |
boolean | true | Valores lógicos |
undefined | undefined | Valor no asignado o ausente |
null | null | Ausencia intencional |
symbol | Symbol('id') | Identificadores únicos |
Los valores primitivos no son objetos y no se modifican. Las operaciones sobre ellos producen otros valores.
3. ¿Cuál es la diferencia entre forEach y map?
Ambos métodos recorren un arreglo y ejecutan una función por cada elemento, pero sirven para propósitos distintos:
forEachejecuta una acción y devuelveundefined. No crea un arreglo con los resultados.mapdevuelve un arreglo nuevo con el resultado de transformar cada elemento.
const numeros = [1, 2, 3];
numeros.forEach((numero) => {
console.log(numero);
});
const dobles = numeros.map((numero) => numero * 2);
console.log(dobles); // [2, 4, 6]
Usa forEach cuando solo necesitas realizar una acción por elemento y map cuando necesitas transformar los datos.
4. ¿Cuál es la diferencia entre fetch y Axios?
fetch es una API disponible en los navegadores modernos. No requiere instalar una dependencia, pero hay que comprobar response.ok: una respuesta HTTP como 404 no rechaza por sí sola la promesa.
async function obtenerUsuarios() {
const respuesta = await fetch('/api/usuarios');
if (!respuesta.ok) {
throw new Error(`Error HTTP: ${respuesta.status}`);
}
return respuesta.json();
}
Axios es una biblioteca externa que normalmente rechaza la promesa ante respuestas HTTP fuera del rango 2xx y convierte respuestas JSON habituales automáticamente.
import axios from 'axios';
const respuesta = await axios.get('/api/usuarios');
console.log(respuesta.data);
fetch es una opción nativa; Axios añade funcionalidades y una interfaz propia. La elección depende de las necesidades del proyecto.
React y TypeScript
5. ¿Cuál es la diferencia entre interface y type en TypeScript?
Ambos pueden describir la forma de un objeto. Una interface puede extenderse con extends y permite combinar declaraciones del mismo nombre. Un alias type puede representar también uniones, intersecciones, tuplas y tipos primitivos, pero no admite esa combinación de declaraciones.
interface Usuario {
nombre: string;
edad: number;
}
interface Administrador extends Usuario {
permisos: string[];
}
type Estado = 'cargando' | 'correcto' | 'error';
type Identificador = number | string;
No hay una regla universal que obligue a usar uno en todos los casos. Conviene elegir según la composición que necesita el tipo y mantener el estilo del proyecto.
6. ¿Cuál es la diferencia entre Redux y Redux Toolkit?
Redux es una biblioteca para administrar estado compartido. Redux Toolkit es el conjunto de herramientas recomendado para escribir aplicaciones Redux: reduce la configuración repetitiva y ofrece funciones como configureStore y createSlice.
import { configureStore, createSlice } from '@reduxjs/toolkit';
const contadorSlice = createSlice({
name: 'contador',
initialState: { valor: 0 },
reducers: {
incrementar(state) {
state.valor += 1;
},
},
});
export const { incrementar } = contadorSlice.actions;
export const store = configureStore({
reducer: {
contador: contadorSlice.reducer,
},
});
En los reducers de Redux Toolkit se puede escribir una actualización que parece mutar el estado. La biblioteca usa Immer para producir el siguiente estado sin modificar directamente el anterior.
7. ¿Qué paquete se puede utilizar para internacionalizar una aplicación?
Una opción común en React es combinar i18next, que administra la configuración y las traducciones, con react-i18next, que facilita su uso desde componentes.
import { useTranslation } from 'react-i18next';
export default function Saludo() {
const { t } = useTranslation();
return <p>{t('bienvenida')}</p>;
}
La clave bienvenida se resuelve con el texto correspondiente al idioma activo, por ejemplo, '¡Bienvenido!'. Hay otras bibliotecas y la elección depende de cómo se necesite organizar y cargar las traducciones.
8. ¿Cuál es la diferencia entre redux-thunk y redux-saga?
Ambos son middleware para coordinar trabajo asíncrono con Redux, pero utilizan enfoques distintos:
redux-thunkpermite que una acción sea una función. Es una opción sencilla para operaciones como solicitar datos y después enviar acciones.redux-sagautiliza funciones generadoras y efectos comocallyput. Puede resultar útil para flujos que requieren coordinación, cancelación o concurrencia.
Ejemplo conceptual con Thunk:
const cargarUsuarios = () => async (dispatch) => {
dispatch({ type: 'usuarios/cargando' });
try {
const respuesta = await fetch('/api/usuarios');
if (!respuesta.ok) {
throw new Error(`Error HTTP: ${respuesta.status}`);
}
const usuarios = await respuesta.json();
dispatch({ type: 'usuarios/cargados', payload: usuarios });
} catch (error) {
dispatch({
type: 'usuarios/error',
payload: error instanceof Error ? error.message : 'Error desconocido',
});
}
};
Redux Toolkit incluye Thunk en su middleware predeterminado. Saga se configura aparte; no hace falta añadirlo cuando el flujo asíncrono del proyecto se resuelve con Thunk.
CSS
9. ¿Qué es el modelo de caja?
El modelo de caja describe el espacio que ocupa un elemento. Desde dentro hacia fuera, sus partes son el contenido, el relleno (padding), el borde (border) y el margen (margin).
.caja {
width: 200px;
padding: 20px;
border: 5px solid currentColor;
margin: 10px;
}
Con el valor predeterminado box-sizing: content-box, los 200px corresponden solo al contenido. El ancho exterior sin márgenes es 250px: 200 de contenido, 40 de relleno y 10 de bordes.
Con box-sizing: border-box, el ancho declarado incluye el contenido, el relleno y el borde:
* {
box-sizing: border-box;
}
Esta configuración hace más predecible el tamaño total de los elementos.
Ejercicio práctico: mostrar datos en tarjetas
Supón que recibes datos simulados y debes representarlos con Card.tsx, CardContainer.tsx y App.tsx. Cada componente tiene una responsabilidad: presentar un elemento, recorrer la colección y proporcionar los datos.
Card.tsx
type CardProps = {
nombre: string;
descripcion: string;
};
export default function Card({ nombre, descripcion }: CardProps) {
return (
<article>
<h2>{nombre}</h2>
<p>{descripcion}</p>
</article>
);
}
CardContainer.tsx
import Card from './Card';
type Elemento = {
id: number;
nombre: string;
descripcion: string;
};
type CardContainerProps = {
elementos: Elemento[];
};
export default function CardContainer({ elementos }: CardContainerProps) {
return (
<section aria-label="Lista de elementos">
{elementos.map((elemento) => (
<Card
key={elemento.id}
nombre={elemento.nombre}
descripcion={elemento.descripcion}
/>
))}
</section>
);
}
La propiedad key debe ser única y estable entre los elementos renderizados. Por eso se usa id, no el índice del arreglo cuando hay un identificador disponible.
App.tsx
import CardContainer from './CardContainer';
const datos = [
{
id: 1,
nombre: 'Tarjeta 1',
descripcion: 'Descripción del primer elemento.',
},
{
id: 2,
nombre: 'Tarjeta 2',
descripcion: 'Descripción del segundo elemento.',
},
{
id: 3,
nombre: 'Tarjeta 3',
descripcion: 'Descripción del tercer elemento.',
},
];
export default function App() {
return (
<main>
<h1>Lista de elementos</h1>
<CardContainer elementos={datos} />
</main>
);
}
Al adaptar el ejercicio a datos reales, define los tipos según los campos recibidos y comprueba que los nombres de las propiedades coincidan. Si los objetos incluyen imágenes o fechas, agrega esos campos a los tipos y decide cómo presentarlos en la tarjeta.
© Arturo Juárez Monroy