00:00 / 00:00
Bye React.memo
En el ejemplo anterior creamos un proyecto en blanco y le metimos soporte a React Compiler.
Ahora vamos a ver como podemos optimizar a la antigua un componente con React.memo
y ver que pasa si metemos el complicador en el proyecto.
Antes de ponernos manos a la obra, hacemos un poco de limpia en el proyecto semilla:
Borramos de
public
y./src/assets
imagenes que no vams a usar.Creamos un fichero
demo.tsx
en la raíz del proyecto.Y añadimos un componente tonto que se va a llamar
MyComponent
.
Y ahora sí, vamos al lío, lo primero que vamos a hacer es deshabilitar el compilador y ver como optimizar sin su ayuda, utilizando React.memo
.
Deshabilitamos el compilador:
./vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
// https://vite.dev/config/
export default defineConfig({
plugins: [
react(
+ /*
{
babel: {
plugins: [["babel-plugin-react-compiler", { target: "19" }]],
},
}
+ */
),
],
});
Y en el fichero demo.tsx
vamos a añadir el siguiente código:
import React from "react";
interface Props {
name: string;
}
export const DisplayUsername = (props: Props) => {
console.log(
"Hey I'm only rerendered when name gets updated, check React.memo"
);
return <h3>{props.name}</h3>;
};
export const MyComponent = () => {
const [userInfo, setUserInfo] = React.useState({
name: " John ",
lastname: "Doe",
});
return (
<>
<DisplayUsername name={userInfo.name} />
<input
value={userInfo.name}
onChange={(e) =>
setUserInfo({
...userInfo,
name: e.target.value,
})
}
/>
<input
value={userInfo.lastname}
onChange={(e) =>
setUserInfo({
...userInfo,
lastname: e.target.value,
})
}
/>
</>
);
};
¿Qué estamos haciendo aquí?
Tenemos un useState que guarda un objeto con los campos
nombre
yapellidos
.Tenemos un componente
DisplayUsername
que recibe el nombre y lo muestra en unh3
.El apellido directamente lo mostramos en el mismo component.
Tenemos dos inputs, uno para el nombre y otro para el apellido.
Ojo esto es un ejemplo muy simplificado y forzado para ver el comportamiento de React.memo.
Si te fijas DisplayUsername
sólo recibe como props la propiedad name
, por lo que si cambiamos el apellido, no debería de volver a renderizarse ¿O sí? Si lo probamos... cada vez que cambiamos nombre o apellido, displayUsername
se renderiza.
¿Cómo optimizabamos esto en la era precompilador
con React.memo
?
- export const DisplayUsername = (props: Props) => {
+ export const DisplayUsername = React.memo((props: Props) => {
console.log(
"Hey I'm only rerendered when name gets updated, check React.memo"
);
return <h3>{props.name}</h3>;
- };
+ });
Si ahora ejecutamos podemos ver como DisplayUsername
sólo se renderiza cuando cambiamos el nombre.
¿Probamos con el compilador?
Activamos el compilador de nuevo
./vite.config.ts
export default defineConfig({
plugins: [
react(),
- /*{
+ {
babel: {
plugins: [["babel-plugin-react-compiler", { target: "19" }]],
},
+ }
- }*/
],
});
Vamos a eliminar ese React.memo
y vamos a ver que ocurre.
+ export const DisplayUsername = (props: Props) => {
- export const DisplayUsername = React.memo((props: Props) => {
console.log(
"Hey I'm only rerendered when name gets updated, check React.memo"
);
return <h3>{props.name}</h3>;
+ };
- });
Ejecutamos, abrimos la consola y.... ¡¡ funciona !!
Sin duda alguna los mejores avances en librerías, son lo que nos permiten olvidarnos de ellos y centrarnos en lo que realmente importa, en este caso, en la lógica de nuestra aplicación.