A veces uso este patrón donde declaro una función curry dentro useCallback .
const Child = ({ handleClick }) => { return ( <> <button onClick={handleClick("foo")}>foo</button> <button onClick={handleClick("lorem")}>lorem</button> </> ); }; export default function App() { const [state, setState] = useState(""); const handleClick = useCallback( (newState) => () => { setState(newState); }, [] ); return ( <div className="App"> <Child handleClick={handleClick} /> <p>{state}</p> </div> ); }porque quiero pasar argumentos de JSX a los controladores de eventos y evitar múltiples controladores.
Cuando el componente se vuelve a representar, se llamará a handleClick y la función que se devuelve se asignará a onClick prop, pero ¿será una función nueva cada vez o useCallback también memorizará la función anidada?
PD: Este es un ejemplo simple. Suponga un uso de useCallback con múltiples dependencias
La siguiente respuesta se refiere a la versión inicial del código de OP en el que handleClick no se pasó como accesorio al componente Child .
Realmente no necesita useCallback en este caso.
En realidad, sería mejor no usar el hook useCallback en este caso porque:
La función de devolución de llamada que se pasa a useCallback se crea cada vez que su componente se vuelve a renderizar. Como resultado, se crea una nueva función de todos modos, tal como lo haría sin el uso de useCallback
Obtener una versión memorizada de la función handleClick no brinda ningún beneficio en su caso. La memorización sería útil si handleClick se pasa como accesorio a los componentes secundarios.
... pero ¿será una función nueva cada vez o la función anidada también será memorizada por useCallback?
No, la función anidada no se memorizará.
handleClick es una función memorizada pero esa función memorizada devuelve una nueva función cada vez que se ejecuta.
Invocar handleClick es como invocar cualquier otra función: cualquier cosa declarada dentro de su cuerpo se crea cada vez que se invoca.
Debería, curry o no, es una instancia de función, siempre que desee mantener una instancia de función anterior, puede usarla.
Pero no lo use porque el accesorio onClick , porque cuando su componente se renderiza, este button tiene que renderizarse independientemente del onClick . Entonces su línea puede ser simplemente como
const onClick = value => () => { setState(value) }O incluso puede promover esto a una función global.
const handle = setState => value => () => { setState(value) } NOTA: no quiero decir que useCallback mayor parte del tiempo sea inútil. Pero en realidad, si no sabe por qué quiere usar un useMemo , no use un useCallback . Están diseñados para omitir una tarea, pero no para omitir un procesamiento o, en su caso, para mejorar la reutilización. (no para ese fin).