Estoy tratando de hacer que mi código sea limpio y legible. Así que decidí crear un enlace personalizado para almacenar allí mis useState . Luego creé un nuevo archivo para almacenar mi detector de eventos. Ahora, tengo tres archivos: Page.js , useStates.js y Listeners.js .
El problema es que no puedo usar mis estados en detectores de eventos.
Traté de almacenar mis estados en variables de alcance global en useStates.js y pasarlos con captadores. Pero no funcionó porque actualizar el estado no cambió la página (pero sí se volvió a renderizar).
useStates.js :
import react, { useState } from 'react'; export default () => { const [myState, setMyState] = useState(false); return { myState, setMyState }; } Page.js :
import react from 'react'; import useStates from './useStates'; import { someActionListener } from './listeners'; export default () => { const states = useStates(); return <SomeComponent somProp={states.myState} onSomeAction={ someActionListener } /> } Listeners.js :
export const someActionListener = (e) => { // This should be done states.setMyState(!states.myState); }Podrías pasar los states al oyente:
export const someActionListener = (e, states) => { // This should be done states.setMyState(!states.myState); }...
<SomeComponent somProp={states.myState} onSomeAction={e => someActionListener(e, states)} /> O curry el valor de los states en su lugar, lo que lleva a una interfaz de usuario más limpia, guarda la devolución de llamada de la función anónima:
export const someActionListener = states => e => { // This should be done states.setMyState(!states.myState); }...
<SomeComponent somProp={states.myState} onSomeAction={someActionListener(states)} />Sugiero ajustar el oyente de acción para que acepte una devolución de llamada. Los detectores de eventos suelen hacer esto de todos modos. Una función curry es una manera fácil de cerrar una devolución de llamada y devolver la devolución de llamada del detector de eventos. Esto desacopla el estado y la actualización de estado de la lógica del detector de eventos, lo que permite que el componente React use ambos para mantener el control del estado y cómo se actualiza.
export const someActionListener = (callback) => (e) => { // This should be done callback(); }Pase la función de actualización de estado como una devolución de llamada.
export default () => { const states = useStates(); return ( <SomeComponent somProp={states.myState} onSomeAction={someActionListener( () => states.setMyState(!states.myState)) )} /> ); }O usando una actualización de estado funcional ya que está alternando un valor de estado. Esto es para evitar recintos de estado obsoletos en las devoluciones de llamada.
<SomeComponent somProp={states.myState} onSomeAction={someActionListener( () => states.setMyState(states => ({ ...states myState: !states.myState }) } />