You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: beta/src/content/apis/react/useCallback.md
+53-53Lines changed: 53 additions & 53 deletions
Original file line number
Diff line number
Diff line change
@@ -618,11 +618,11 @@ Ten en cuenta que necesitas correr React en modo de producción, deshabilitar [R
618
618
619
619
---
620
620
621
-
### Updating state from a memoized callback {/*updating-state-from-a-memoized-callback*/}
621
+
### Actualizar estado de un callback almacenado {/*updating-state-from-a-memoized-callback*/}
622
622
623
-
Sometimes, you might need to update state based on previous state from a memoized callback.
623
+
En ocasiones, podrías necesitar actualizar el estado basado en su valor anterior desde un callback almacenado.
624
624
625
-
This `handleAddTodo`function specifies `todos`as a dependency because it computes the next todos from it:
625
+
La función `handleAddTodo`especifica `todos`como una dependencia, porque calcula los siguientes *todos* a partir de ella:
626
626
627
627
```js {6,7}
628
628
functionTodoList() {
@@ -635,7 +635,7 @@ function TodoList() {
635
635
// ...
636
636
```
637
637
638
-
You'll usually want your memoized functions to have as few dependencies as possible. When you read some state only to calculate the next state, you can remove that dependency by passing an [updater function](/apis/react/useState#updating-state-based-on-the-previous-state) instead:
638
+
Por lo general es mejor que tus funciones almacenadas tengan el menor número de dependencias posibles. Cuando lees un estado solamente para calcular un estado subsecuente, puedes remover esa dependencia al enviar una [función de actualización](/apis/react/useState#updating-state-based-on-the-previous-state) en su lugar:
639
639
640
640
```js {6,7}
641
641
functionTodoList() {
@@ -644,17 +644,17 @@ function TodoList() {
644
644
consthandleAddTodo=useCallback((text) => {
645
645
constnewTodo= { id: nextId++, text };
646
646
setTodos(todos=> [...todos, newTodo]);
647
-
}, []); // ✅ No need for the todos dependency
647
+
}, []); // ✅ No se necesita la dependencia todos
648
648
// ...
649
649
```
650
650
651
-
Here, instead of making `todos`a dependency of your function and reading it there, you pass an instruction about *how* to update the state (`todos=> [...todos, newTodo]`) to React. [Read more about updater functions.](/apis/react/useState#updating-state-based-on-the-previous-state)
651
+
Aquí, en lugar de hacer que `todos`sea una dependencia de tu función y leerla allí, envías a React una instrucción sobre *cómo* actualizar el estado (`todos=> [...todos, newTodo]`). [Lee más sobre las funciones de actualización.](/apis/react/useState#updating-state-based-on-the-previous-state)
652
652
653
653
---
654
654
655
-
### Preventing an Effect from firing too often {/*preventing-an-effect-from-firing-too-often*/}
655
+
### Prevenir que un Efecto se dispare frecuentemente {/*preventing-an-effect-from-firing-too-often*/}
656
656
657
-
Sometimes, you might want to call a function from inside an [Effect:](/learn/synchronizing-with-effects)
657
+
En ocasiones, es posible que desees llamar a una función desde un [Efecto:](/learn/synchronizing-with-effects)
658
658
659
659
```js {4-9,12}
660
660
functionChatRoom({ roomId }) {
@@ -674,20 +674,19 @@ function ChatRoom({ roomId }) {
674
674
// ...
675
675
```
676
676
677
-
This creates a problem. [Every reactive value must be declared as a dependency of your Effect.](/learn/lifecycle-of-reactive-effects#react-verifies-that-you-specified-every-reactive-value-as-a-dependency) However, if you declare `createOptions` as a dependency, it will cause your Effect to constantly reconnect to the chat room:
678
-
677
+
Esto genera un problema. [Todo valor reactivo debe ser declarado como una dependencia de tu Efecto.](/learn/lifecycle-of-reactive-effects#react-verifies-that-you-specified-every-reactive-value-as-a-dependency) Sin embargo, si declaras `createOptions` como una dependencia, esto provocará que tu Efecto se reconecte constantemente al chat:
679
678
680
679
```js {6}
681
680
useEffect(() => {
682
681
constoptions=createOptions();
683
682
constconnection=createConnection();
684
683
connection.connect();
685
684
return () =>connection.disconnect();
686
-
}, [createOptions]); // 🔴 Problem: This dependency changes on every render
685
+
}, [createOptions]); // 🔴 Problema: Esta dependencia cambia en cada renderizado
687
686
// ...
688
687
```
689
688
690
-
To solve this, you can wrap the function you need to call from an Effect into`useCallback`:
689
+
Para solventar esto, puedes envolver la función que necesitas llamar desde un Efecto con`useCallback`:
691
690
692
691
```js {4-9,16}
693
692
functionChatRoom({ roomId }) {
@@ -698,25 +697,25 @@ function ChatRoom({ roomId }) {
698
697
serverUrl:'https://localhost:1234',
699
698
roomId: roomId
700
699
};
701
-
}, [roomId]); // ✅ Only changes when roomId changes
700
+
}, [roomId]); // ✅ Solo cambia cuando roomId cambia
702
701
703
702
useEffect(() => {
704
703
constoptions=createOptions();
705
704
constconnection=createConnection();
706
705
connection.connect();
707
706
return () =>connection.disconnect();
708
-
}, [createOptions]); // ✅ Only changes when createOptions changes
707
+
}, [createOptions]); // ✅ Solo cambia cuando createOptions cambia
709
708
// ...
710
709
```
711
710
712
-
This ensures that the `createOptions`function is the same between re-renders if the`roomId`is the same. **However, it's even better to remove the need for a function dependency.** Move your function *inside* the Effect:
711
+
Esto asegura que la función `createOptions`sea la misma entre renderizados subsecuentes, siempre que`roomId`sea el mismo. **Sin embargo, es aún mejor remover la necesidad de una dependencia en la función.** Mueve tu función *dentro* del Efecto:
713
712
714
713
```js {5-10,16}
715
714
functionChatRoom({ roomId }) {
716
715
const [message, setMessage] =useState('');
717
716
718
717
useEffect(() => {
719
-
functioncreateOptions() { // ✅ No need for useCallback or function dependencies!
718
+
functioncreateOptions() { // ✅ No es necesario usar useCallback ni dependencias de función
720
719
return {
721
720
serverUrl:'https://localhost:1234',
722
721
roomId: roomId
@@ -727,17 +726,17 @@ function ChatRoom({ roomId }) {
727
726
constconnection=createConnection();
728
727
connection.connect();
729
728
return () =>connection.disconnect();
730
-
}, [roomId]); // ✅ Only changes when roomId changes
729
+
}, [roomId]); // ✅ Solo cambia cuando roomId cambia
731
730
// ...
732
731
```
733
732
734
-
Now your code is simpler and doesn't need `useCallback`. [Learn more about removing Effect dependencies.](/learn/removing-effect-dependencies#move-dynamic-objects-and-functions-inside-your-effect)
733
+
Ahora tu código es mucho más simple y no requiere de `useCallback`. [Aprende más sobre remover dependencias de Efectos.](/learn/removing-effect-dependencies#move-dynamic-objects-and-functions-inside-your-effect)
735
734
736
735
---
737
736
738
-
### Optimizing a custom Hook {/*optimizing-a-custom-hook*/}
737
+
### Optimizar un Hook personalizado {/*optimizing-a-custom-hook*/}
739
738
740
-
If you're writing a [custom Hook,](/learn/reusing-logic-with-custom-hooks) it's recommended to wrap any functions that it returns into`useCallback`:
739
+
Si estás escribiendo un [Hook personalizado,](/learn/reusing-logic-with-custom-hooks) es recomendable envolver cualquier función que el Hook retorne con`useCallback`:
741
740
742
741
```js {4-6,8-10}
743
742
functionuseRouter() {
@@ -758,15 +757,15 @@ function useRouter() {
758
757
}
759
758
```
760
759
761
-
This ensures that the consumers of your Hook can optimize their own code when needed.
760
+
Esto asegura que los consumidores de tu Hook puedan optimizar su propio código cuando sea necesario.
[Observa más ejemplos arriba.](#examples-rerendering)
784
783
785
-
#### Parameters {/*parameters*/}
784
+
#### Parámetros {/*parameters*/}
786
785
787
-
* `fn`: The function value that you want to memoize. It can take any arguments and return any values. React will return (not call!) your function back to you during the initial render. On subsequent renders, React will return the same function again if the `dependencies` have not changed since the last render. Otherwise, it will give you the function that you have passed during the current render, and store it in case it can be reused later. React will not call the function. The function is returned to you so you can decide when and whether to call it.
786
+
* `fn`: La función que deseas almacenar. Puede recibir cualquier argumento y devolver cualquier valor. React retornará (¡no llamará!) tu función durante el renderizado inicial. En los renderizados subsecuentes, React retornará la misma función nuevamente si las `dependencias` no han cambiado desde el último renderizado. Si no es así, React retornará la función que pasaste durante el renderizado actual, y la almacenará en caso de que se necesite reutilizar más adelante. React no llamará a la función. La función será retornada para que puedas decidir si y cuándo llamarla.
788
787
789
-
* `dependencies`: The list of all reactive values referenced inside of the `fn` code. Reactive values include props, state, and all the variables and functions declared directly inside your component body. If your linter is [configured for React](/learn/editor-setup#linting), it will verify that every reactive value is correctly specified as a dependency. The list of dependencies must have a constant number of items and be written inline like `[dep1, dep2, dep3]`. React will compare each dependency with its previous value using the [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) comparison algorithm.
788
+
* `dependencias`: La lista de todos los valores reactivos dentro de la función `fn`. Los valores reactivos incluyen props, estado y todas las variables y funciones declaradas directamente dentro del cuerpo de tu componente. Si tu *linter* está [configurado para React](/learn/editor-setup#linting), verificará que cada valor reactivo esté debidamente especificado como una dependencia. La lista de dependencias debe tener un número constante de elementos y estar escrita en línea, de la forma `[dep1, dep2, dep3]`. React comparará cada dependencia con su valor anterior usando el algoritmo de comparación [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is).
790
789
791
-
#### Returns {/*returns*/}
790
+
#### Retornos {/*returns*/}
792
791
793
-
On the initial render, `useCallback`returns the `fn`function you have passed.
792
+
En el renderizado inicial, `useCallback`retorna la función `fn`que le has enviado.
794
793
795
-
During subsequent renders, it will either return an already stored `fn` function from the last render (if the dependencies haven't changed), or return the `fn` function you have passed during this render.
794
+
Durante los renderizados siguientes, puede retornar una función `fn` ya almacenada desde el último renderizado
795
+
(si las dependencias no han cambiado), o retornar la función `fn` que hayas enviado durante el renderizado actual.
796
796
797
-
#### Caveats {/*caveats*/}
797
+
#### Advertencias {/*caveats*/}
798
798
799
-
* `useCallback`is a Hook, so you can only call it **at the top level of your component** or your own Hooks. You can't call it inside loops or conditions. If you need that, extract a new component and move the state into it.
800
-
* React **will not throw away the cached function unless there is a specific reason to do that.** For example, in development, React throws away the cache when you edit the file of your component. Both in development and in production, React will throw away the cache if your component suspends during the initial mount. In the future, React may add more features that take advantage of throwing away the cache--for example, if React adds built-in support for virtualized lists in the future, it would make sense to throw away the cache for items that scroll out of the virtualized table viewport. This should match your expectations if you rely on`useCallback`as a performance optimization. Otherwise, a [state variable](/apis/react/useState#im-trying-to-set-state-to-a-function-but-it-gets-called-instead) or a [ref](/apis/react/useRef#avoiding-recreating-the-ref-contents) may be more appropriate.
799
+
* `useCallback`es un Hook, por lo que solo puedes llamarlo **en el nivel superior de tu componente** o en tus propios Hooks. No puedes llamarlo dentro de un ciclo ni de una condición. Si necesitas hacerlo, debes extraer un nuevo componente y mover el estado a él.
800
+
* React **no descartará la función almacenada a menos que haya una razón específica para hacerlo.** Por ejemplo, en el ambiente de desarrollo, React descarta el caché cuando editas algún archivo de tu componente. Tanto en desarrollo como en producción, React descartará el caché si tu componente se suspende durante el monaje inicial. En el futuro, es posible que React agregue más características que aprovechen el descarte del caché--por ejemplo, si React agrega soporte nativo para listas virtuales en el futuro, tendría sentido descartar el caché para los elementos que estén fuera de la vista de la tabla virtualizada. Esto debería cumplir con tus expectativas si dependes de`useCallback`como una optimización de rendimiento. De lo contrario, una [variable de estado](/apis/react/useState#im-trying-to-set-state-to-a-function-but-it-gets-called-instead) o una [referencia](/apis/react/useRef#avoiding-recreating-the-ref-contents) podrían ser más apropiadas.
801
801
802
802
---
803
803
804
-
## Troubleshooting {/*troubleshooting*/}
804
+
## Resolución de Problemas {/*troubleshooting*/}
805
805
806
-
### Every time my component renders, `useCallback`returns a different function {/*every-time-my-component-renders-usecallback-returns-a-different-function*/}
806
+
### Cada ves que mi componente se renderiza, `useCallback`retorna una función diferente {/*every-time-my-component-renders-usecallback-returns-a-different-function*/}
807
807
808
-
Make sure you've specified the dependency array as a second argument!
808
+
¡Asegúrate de haber especificado el *array* de dependencias como un segundo argumento!
809
809
810
-
If you forget the dependency array, `useCallback`will return a new function every time:
810
+
Si olvidas el *array* de dependencias, `useCallback`retornará una nueva función cada vez:
811
811
812
812
```js {7}
813
813
functionProductPage({ productId, referrer }) {
@@ -816,11 +816,11 @@ function ProductPage({ productId, referrer }) {
816
816
referrer,
817
817
orderDetails,
818
818
});
819
-
}); // 🔴 Returns a new function every time: no dependency array
819
+
}); // 🔴 Retorna una función cada vez: no existe un array de dependencias
820
820
// ...
821
821
```
822
822
823
-
This is the corrected version passing the dependency array as a second argument:
823
+
Esta es la versión corregida, enviando el *array* de dependencias como segundo argumento:
824
824
825
825
```js {7}
826
826
functionProductPage({ productId, referrer }) {
@@ -829,11 +829,11 @@ function ProductPage({ productId, referrer }) {
829
829
referrer,
830
830
orderDetails,
831
831
});
832
-
}, [productId, referrer]); // ✅ Does not return a new function unnecessarily
832
+
}, [productId, referrer]); // ✅ No retorna una nueva función innecesariamente
833
833
// ...
834
834
```
835
835
836
-
If this doesn't help, then the problem is that at least one of your dependencies is different from the previous render. You can debug this problem by manually logging your dependencies to the console:
836
+
Si esto no ayuda, entonces el problema es que al menos una de tus dependencias es diferente al renderizado anterior. Puedes depurar este problema manualmente registrando tus dependencias en la consola:
837
837
838
838
```js {5}
839
839
consthandleSubmit=useCallback((orderDetails) => {
@@ -843,28 +843,28 @@ If this doesn't help, then the problem is that at least one of your dependencies
843
843
console.log([productId, referrer]);
844
844
```
845
845
846
-
You can then right-click on the arrays from different re-renders in the console and select "Store as a global variable" for both of them. Assuming the first one got saved as `temp1`and the second one got saved as `temp2`, you can then use the browser console to check whether each dependency in both arrays is the same:
846
+
Después, puedes hacer click derecho en los *arrays* de diferentes renderizados en la consola y seleccionar la opción de "Guardar como variable global" para ambos. Suponiendo que el primero se haya guardado con el nombre `temp1`y el segundo con el nombre `temp2`, puedes usar la consola del navegador para verificar si cada dependencia en ambos *arrays* es la misma:
847
847
848
848
```js
849
-
Object.is(temp1[0], temp2[0]); //Is the first dependency the same between the arrays?
850
-
Object.is(temp1[1], temp2[1]); //Is the second dependency the same between the arrays?
851
-
Object.is(temp1[2], temp2[2]); // ... and so on for every dependency ...
849
+
Object.is(temp1[0], temp2[0]); //¿Es la primera dependencia la misma entre los arrays?
850
+
Object.is(temp1[1], temp2[1]); //¿Es la segunda dependencia la misma entre los arrays?
851
+
Object.is(temp1[2], temp2[2]); // ... y así consecutivamente para cada dependencia ...
852
852
```
853
853
854
-
When you find which dependency is breaking memoization, either find a way to remove it, or [memoize it as well.](/apis/react/useMemo#memoizing-a-dependency-of-another-hook)
854
+
Cuando encuentres cuál dependencia está rompiendo la memoización, puedes encontrar una manera de removerla o [memoizarla también.](/apis/react/useMemo#memoizing-a-dependency-of-another-hook)
855
855
856
856
---
857
857
858
-
### I need to call `useCallback`for each list item in a loop, but it's not allowed {/*i-need-to-call-usememo-for-each-list-item-in-a-loop-but-its-not-allowed*/}
858
+
### Necesito llamar `useCallback`para cada elemento de una lista dentro de un ciclo, pero no es permitido {/*i-need-to-call-usememo-for-each-list-item-in-a-loop-but-its-not-allowed*/}
859
859
860
-
Suppose the `Chart`component is wrapped in [`memo`](/api/react/memo). You want to skip re-rendering every `Chart`in the list when the `ReportList`component re-renders. However, you can't call `useCallback`in a loop:
860
+
Suponiendo que el componente `Chart`está envuelto en [`memo`](/api/react/memo). Deseas omitir el re-renderizado en cada `Chart`en la lista cuando el componente `ReportList`se re-renderiza. Sin embargo, no puedes llamar a `useCallback`dentro de un ciclo:
861
861
862
862
```js {5-14}
863
863
functionReportList({ items }) {
864
864
return (
865
865
<article>
866
866
{items.map(item=> {
867
-
// 🔴 You can't call useCallback in a loop like this:
867
+
// 🔴 No puedes llamar a useCallback dentro de un ciclo así:
868
868
consthandleClick=useCallback(() => {
869
869
sendReport(item)
870
870
}, [item]);
@@ -880,7 +880,7 @@ function ReportList({ items }) {
880
880
}
881
881
```
882
882
883
-
Instead, extract a component for an individual item, and put`useCallback`there:
883
+
En su lugar, extrae un componente para un elemento individual, y coloca`useCallback`allí:
884
884
885
885
```js {5,12-21}
886
886
functionReportList({ items }) {
@@ -894,7 +894,7 @@ function ReportList({ items }) {
894
894
}
895
895
896
896
functionReport({ item }) {
897
-
// ✅ Call useCallback at the top level:
897
+
// ✅ Llama a useCallback en el nivel superior:
898
898
consthandleClick=useCallback(() => {
899
899
sendReport(item)
900
900
}, [item]);
@@ -907,7 +907,7 @@ function Report({ item }) {
907
907
}
908
908
```
909
909
910
-
Alternatively, you could remove `useCallback`in the last snippet and instead wrap `Report`itself in [`memo`.](/api/react/memo) If the `item`prop does not change, `Report`will skip re-rendering, so `Chart`will skip re-rendering too:
910
+
De forma alternativa, podrías remover `useCallback`en el último fragmento y envolver `Report`con [`memo`](/api/react/memo) en su lugar. Si la prop `item`no cambia, `Report`omitirá el re-renderizado, por lo que `Chart`también lo hará:
0 commit comments