Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

354
Vistas
useState polyfill, ¿es correcto?

Intentando escribir una implementación personalizada de useState. Digamos solo para un solo valor.

 function useMyState(initVal){ const obj = { value: initVal, get stateValGet() { return this.value }, set stateValSet(val) { this.value = val } }; const setVal = (val) => { obj.stateValSet = val } return [obj.stateValGet, setVal] }

Sin embargo, no parece funcionar, ¿alguien puede decir por qué? No se puede descifrar esto.

Devuelve este [, <function_setter>] Entonces, si intenta ejecutar este método setVal, activa el setter. Pero getter nunca recibe una llamada a la actualización.

about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

Cada administrador de estado que quiera interactuar con React tiene que encontrar una manera de conectarse al ciclo de vida de React, para poder activar re-renderizaciones en el cambio de estado. El gancho useState usa internamente useReducer : https://github.com/facebook/react/blob/16.8.6/packages/react-dom/src/server/ReactPartialRendererHooks.js#L254

Es por eso que hice esta implementación ingenua de useState basada en JS Proxies y un envío ficticio de useReducer solo para forzar una nueva representación cuando cambia el estado.

Es ingenuo, pero en eso se basa valtio .

Considere que el poder de los proxies permitiría activar re-renderizaciones mutando el estado directamente, ¡eso es lo que sucede en valtio !

 import { useReducer, useCallback, useMemo } from 'react'; export const useMyState = (_state) => { // FORCE RERENDER const [, rerender] = useReducer(() => ({})); const forceUpdate = useCallback(() => rerender({}), []); // INITIALIZE STATE AS A MEMOIZED PROXY const { proxy, set } = useMemo(() => { const target = { state: _state, }; // Place a trap on setter, to trigger a component rerender const handler = { set(target, prop, value) { console.log('SETTING', target, prop, value); target[prop] = value; forceUpdate(); return true; }, }; const proxy = new Proxy(target, handler); const set = (d) => { const value = typeof d === 'function' ? d(proxy.state) : d; if (value !== proxy.state) proxy.state = value; }; return { proxy, set }; }, []); return [proxy.state, set]; };

Demostración https://stackblitz.com/edit/react-33fpbk?file=src%2FApp.js

about 4 years ago · Juan Pablo Isaza Denunciar

0

La funcionalidad de useState realmente no se puede policompletar o sustituir con su propia implementación personalizada, porque no solo almacena el estado, sino que también activa una nueva representación del componente cuando se llama al setter de estado. La activación de una nueva representación de este tipo solo es posible con acceso a las partes internas de React, a las que la API de superficie disponible para nosotros no tiene acceso.

useState no se puede reemplazar con su propia implementación a menos que esa implementación también use useState para obtener el componente en el que se usa para volver a renderizar cuando se llama al setter de estado.

Sin embargo, podría crear su propia implementación personalizada fuera de React, una que simule una nueva representación llamando a una función nuevamente cuando se llama al setter de estado.

 const render = () => { console.log('rendering'); const [value, setValue] = useMyState(0); document.querySelector('.root').textContent = value; const button = document.querySelector('.root') .appendChild(document.createElement('button')); button.addEventListener('click', () => setValue(value + 1)); button.textContent = 'increment'; }; const useMyState = (() => { let mounted = false; let currentState; return (initialValue) => { if (!mounted) { mounted = true; currentState = initialValue; } return [ currentState, (newState) => { currentState = newState; render(); } ]; }; })(); render();
 <div class="root"></div>

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda