Files
mintlify[bot] 4b465465dd translate: mirror boost: 3 frontmatter to es/fr/zh translations (#5671)
Generated-By: mintlify-agent

Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
2026-05-05 17:33:20 +00:00

258 lines
9.2 KiB
Plaintext

---
title: "React"
description: "Crea elementos interactivos y reutilizables con componentes de React personalizados en tu documentación de Mintlify usando JSX, estado y lógica del lado del cliente."
keywords: ["React components", "interactive components", "JSX", "custom components"]
boost: 3
---
import { ColorGenerator } from "/snippets/color-generator.jsx";
Los [componentes de React](https://react.dev) son una forma eficaz de crear elementos interactivos y reutilizables en tu documentación.
<div id="using-react-components">
## Uso de componentes de React
</div>
Puedes crear componentes de React directamente en tus archivos MDX mediante [hooks de React](https://react.dev/reference/react/hooks).
<div id="example">
### Ejemplo
</div>
Este ejemplo declara un componente `Counter` y luego lo utiliza con `<Counter />`.
```mdx
export const Counter = () => {
const [count, setCount] = useState(0)
const increment = () => setCount(count + 1)
const decrement = () => setCount(count - 1)
return (
<div className="flex items-center justify-center">
<div className="flex items-center rounded-xl overflow-hidden border border-zinc-950/20 dark:border-white/20">
<button
onClick={decrement}
className="flex items-center justify-center h-8 w-8 text-zinc-950/80 dark:text-white/80 border-r border-zinc-950/20 dark:border-white/20"
aria-label="Disminuir"
>
-
</button>
<div className="flex text-sm items-center justify-center h-8 px-6 text-zinc-950/80 dark:text-white/80 font-medium min-w-[4rem] text-center">
{count}
</div>
<button
onClick={increment}
className="flex items-center justify-center h-8 w-8 text-zinc-950/80 dark:text-white/80 border-l border-zinc-950/20 dark:border-white/20"
aria-label="Aumentar"
>
+
</button>
</div>
</div>
)
}
<Counter />
```
export const Counter = () => {
const [count, setCount] = useState(0)
const increment = () => setCount(count + 1)
const decrement = () => setCount(count - 1)
return (
<div className="flex items-center justify-center">
<div className="flex items-center rounded-xl overflow-hidden border border-zinc-950/20 dark:border-white/20">
<button
onClick={decrement}
className="flex items-center justify-center h-8 w-8 text-zinc-950/80 dark:text-white/80 border-r border-zinc-950/20 dark:border-white/20"
aria-label="Disminuir"
>
-
</button>
<div className="flex text-sm items-center justify-center h-8 px-6 text-zinc-950/80 dark:text-white/80 font-medium min-w-[4rem] text-center">
{count}
</div>
<button
onClick={increment}
className="flex items-center justify-center h-8 w-8 text-zinc-950/80 dark:text-white/80 border-l border-zinc-950/20 dark:border-white/20"
aria-label="Incrementar"
>
+
</button>
</div>
</div>
)
}
El contador se representa como un componente interactivo de React.
<Counter />
<div id="importing-components">
## Importar componentes
</div>
Para importar componentes de React en tus archivos MDX, los archivos de los componentes deben estar ubicados en la carpeta `/snippets/`. Más información sobre [snippets reutilizables](/es/create/reusable-snippets).
<Note>
Las importaciones anidadas no se admiten. Si un componente de React hace referencia a otros componentes, debes importar todos los componentes directamente en el archivo MDX principal en lugar de importar componentes dentro de archivos de componentes.
</Note>
### Ejemplo
Este ejemplo declara un componente `ColorGenerator` que usa varios hooks de React y luego lo utiliza en un archivo MDX.
Crea un archivo llamado `color-generator.jsx` en la carpeta `snippets`:
```mdx /snippets/color-generator.jsx [expandable]
export const ColorGenerator = () => {
const [hue, setHue] = useState(180)
const [saturation, setSaturation] = useState(50)
const [lightness, setLightness] = useState(50)
const [colors, setColors] = useState([])
useEffect(() => {
const newColors = []
for (let i = 0; i < 5; i++) {
const l = Math.max(10, Math.min(90, lightness - 20 + i * 10))
newColors.push(`hsl(${hue}, ${saturation}%, ${l}%)`)
}
setColors(newColors)
}, [hue, saturation, lightness])
const copyToClipboard = (color) => {
navigator.clipboard
.writeText(color)
.then(() => {
console.log(`${color} copiado al portapapeles`)
})
.catch((err) => {
console.error("Error al copiar: ", err)
})
}
return (
<div className="p-4 border dark:border-zinc-950/80 rounded-xl not-prose">
<div className="space-y-4">
<div className="space-y-2">
<label className="block text-sm text-zinc-950/70 dark:text-white/70">
Tono: {hue}°
<input
type="range"
min="0"
max="360"
value={hue}
onChange={(e) => setHue(Number.parseInt(e.target.value))}
className="w-full h-2 bg-zinc-950/20 rounded-lg appearance-none cursor-pointer dark:bg-white/20 mt-1"
style={{
background: `linear-gradient(to right,
hsl(0, ${saturation}%, ${lightness}%),
hsl(60, ${saturation}%, ${lightness}%),
hsl(120, ${saturation}%, ${lightness}%),
hsl(180, ${saturation}%, ${lightness}%),
hsl(240, ${saturation}%, ${lightness}%),
hsl(300, ${saturation}%, ${lightness}%),
hsl(360, ${saturation}%, ${lightness}%))`,
}}
/>
</label>
<label className="block text-sm text-zinc-950/70 dark:text-white/70">
Saturación: {saturation}%
<input
type="range"
min="0"
max="100"
value={saturation}
onChange={(e) => setSaturation(Number.parseInt(e.target.value))}
className="w-full h-2 bg-zinc-950/20 rounded-lg appearance-none cursor-pointer dark:bg-white/20 mt-1"
style={{
background: `linear-gradient(to right,
hsl(${hue}, 0%, ${lightness}%),
hsl(${hue}, 50%, ${lightness}%),
hsl(${hue}, 100%, ${lightness}%))`,
}}
/>
</label>
<label className="block text-sm text-zinc-950/70 dark:text-white/70">
Luminosidad: {lightness}%
<input
type="range"
min="0"
max="100"
value={lightness}
onChange={(e) => setLightness(Number.parseInt(e.target.value))}
className="w-full h-2 bg-zinc-950/20 rounded-lg appearance-none cursor-pointer dark:bg-white/20 mt-1"
style={{
background: `linear-gradient(to right,
hsl(${hue}, ${saturation}%, 0%),
hsl(${hue}, ${saturation}%, 50%),
hsl(${hue}, ${saturation}%, 100%))`,
}}
/>
</label>
</div>
<div className="flex space-x-1">
{colors.map((color, idx) => (
<div
key={idx}
className="h-16 rounded flex-1 cursor-pointer transition-transform hover:scale-105"
style={{ backgroundColor: color }}
title={`Clic para copiar: ${color}`}
onClick={() => copyToClipboard(color)}
/>
))}
</div>
<div className="text-sm font-mono text-zinc-950/70 dark:text-white/70">
<p>
Color base: hsl({hue}, {saturation}%, {lightness}%)
</p>
</div>
</div>
</div>
)
}
```
Importa el componente `ColorGenerator` y úsalo en un archivo MDX:
```mdx
import { ColorGenerator } from "/snippets/color-generator.jsx"
<ColorGenerator />
```
El generador de colores se renderiza como un componente de React interactivo.
<ColorGenerator />
<div id="considerations">
## Consideraciones
</div>
<AccordionGroup>
<Accordion title="Impacto del renderizado en el cliente">
Los componentes que usan hooks de React se renderizan en el cliente, lo que tiene varias implicaciones:
* **SEO**: Es posible que los motores de búsqueda no indexen por completo el contenido dinámico.
* **Carga inicial**: Los visitantes pueden ver un parpadeo de contenido de carga antes de que se rendericen los componentes.
* **Accesibilidad**: Asegúrate de que los cambios en el contenido dinámico se anuncien a los lectores de pantalla.
</Accordion>
<Accordion title="Mejores prácticas de rendimiento">
* **Optimiza los arrays de dependencias**: Incluye solo las dependencias necesarias en tus arrays de dependencias de `useEffect`.
* **Memoriza cálculos complejos**: Usa `useMemo` o `useCallback` para operaciones costosas.
* **Reduce los re-renderizados**: Divide los componentes grandes en otros más pequeños para evitar re-renderizados en cascada.
* **Carga diferida (lazy loading)**: Considera cargar de forma diferida los componentes complejos para mejorar el tiempo de carga inicial de la página.
</Accordion>
</AccordionGroup>