Metaprogramación con React
El propósito no es entrar en detalles sobre qué es la metaprogramación y sus técnicas, sino solo ver un ejemplo de cómo aplicarlo en React.
Esta es mi primera publicación en este fantástico medio, y me gustaría escribir un poco sobre una técnica que ya usamos una vez en nuestras vidas (de un programador), pero que quizás no conozcamos en detalle, ¡la metaprogramación !
El siguiente código es un ejemplo de cómo usar la construcción Proxy y la API Reflect , dentro de un componente React. El componente MyComponent usa el estado local de React ( useState ) para administrar un objeto proxyData que tiene una propiedad de " prueba " inicialmente vacía. El componente tiene tres botones que, al hacer clic, modifican la propiedad "prueba" del objeto proxyData .
import React, { useState } from 'react';
function MyComponent() {
const [proxyData, setProxyData] = useState({ test: '' });
const [render, setRender] = useState(false);
const handleClickMemo = React.useCallback(() => {
const updatedData = new Proxy(proxyData, {
set(target, prop, value) {
const success = Reflect.set(target, prop, value);
if (success) {
console.log(`Prop ${prop} modified with value ${value}`);
}
return success;
},
});
updatedData.test = crypto.randomUUID();
setProxyData(updatedData);
}, []);
// without useCallback, do new proxy every time
const handleClick = () => {
const updatedData = new Proxy(proxyData, {
set(target, prop, value) {
const success = Reflect.set(target, prop, value);
if (success) {
console.warn(`Prop ${prop} modified with value ${value}`);
}
return success;
},
});
updatedData.test = crypto.randomUUID();
setProxyData(updatedData);
};
// case where react doesn't render, but in console,
// if it is a proxy the object is updated
// BE CAREFUL when using proxies
const handleClickNoRender = () => {
proxyData.test = crypto.randomUUID();
setProxyData(proxyData);
};
return (
<div>
<pre>{JSON.stringify(proxyData)}</pre>
<button onClick={handleClickMemo}>handleClickMemo</button>
<button onClick={handleClick}>handleClick</button>
<button onClick={handleClickNoRender}>handleClickNoRender</button>
<br />
<button onClick={() => setRender(!render)}>re-render</button>
</div>
);
}
export default function App() {
return <MyComponent />;
}
El primer botón, handleClickMemo , usa la función React.useCallback para crear una función que React almacena en caché. Esto es útil para evitar que la función se reconstruya cada vez que se actualiza el componente. La función crea un nuevo objeto Proxy basado en el objeto proxyData , actualiza la propiedad "test" con un nuevo valor generado aleatoriamente y establece el estado de proxyData con el objeto recién creado.
const handleClickMemo = React.useCallback(() => {
const updatedData = new Proxy(proxyData, {
set(target, prop, value) {
const success = Reflect.set(target, prop, value);
if (success) {
console.log(`Prop ${prop} modified with value ${value}`);
}
return success;
},
});
updatedData.test = crypto.randomUUID();
setProxyData(updatedData);
}, []);
// without useCallback, do new proxy every time
const handleClick = () => {
const updatedData = new Proxy(proxyData, {
set(target, prop, value) {
const success = Reflect.set(target, prop, value);
if (success) {
console.warn(`Prop ${prop} modified with value ${value}`);
}
return success;
},
});
updatedData.test = crypto.randomUUID();
setProxyData(updatedData);
};
// case where react doesn't render, but in console,
// if it is a proxy the object is updated
// BE CAREFUL when using proxies
const handleClickNoRender = () => {
proxyData.test = crypto.randomUUID();
setProxyData(proxyData);
};
Es importante tener en cuenta que el uso de un Proxy puede tener efectos secundarios y puede causar problemas de rendimiento si no se usa correctamente. Además, es posible que React no detecte la actualización de estados a través de un objeto Proxy , por lo que se debe tener precaución al usar Proxies dentro de un componente React.
En este enlace , puedes ver en la consola el comportamiento de cada botón.

![¿Qué es una lista vinculada, de todos modos? [Parte 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































