Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

141
Views
Problemas con rebote en useEffect

Tengo un formulario con entrada de nombre de usuario y estoy tratando de verificar si el nombre de usuario está en uso o no en una función de rebote. El problema que tengo es que mi rebote no parece funcionar, ya que cuando escribo "usuario" mi consola se ve como

 u us use user

Aquí está mi función de rebote

 export function debounce(func, wait, immediate) { var timeout; return () => { var context = this, args = arguments; var later = () => { timeout = null; if (!immediate) func.apply(context, args); }; var callNow = immediate && !timeout; clearTimeout(timeout); timeout = setTimeout(later, wait); if (callNow) func.apply(context, args); }; };

Y así es como lo llamo en mi componente React

 import React, { useEffect } from 'react' // verify username useEffect(() => { if(state.username !== "") { verify(); } }, [state.username]) const verify = debounce(() => { console.log(state.username) }, 1000);

¿La función de rebote parece ser correcta? ¿Hay algún problema con la forma en que lo estoy llamando en reaccionar?

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

Cada vez que su componente se vuelve a renderizar, se crea una nueva función de verify de rebote, lo que significa que dentro useEffect en realidad está llamando a diferentes funciones que anulan el propósito de la eliminación de rebote.

Es como si estuvieras haciendo algo como esto:

 const debounced1 = debounce(() => { console.log(state.username) }, 1000); debounced1(); const debounced2 = debounce(() => { console.log(state.username) }, 1000); debounced2(); const debounced3 = debounce(() => { console.log(state.username) }, 1000); debounced3();

a diferencia de lo que realmente quieres:

 const debounced = debounce(() => { console.log(state.username) }, 1000); debounced(); debounced(); debounced();

Una forma de resolver esto es usar useCallback , que siempre devolverá la misma devolución de llamada (cuando pasa una matriz vacía como segundo argumento), también, pasaría el nombre de username a esta función en lugar de acceder al estado interno (de lo contrario, estar accediendo a un estado obsoleto):

 import { useCallback } from "react"; const App => () { const [username, setUsername] = useState(""); useEffect(() => { if (username !== "") { verify(username); } }, [username]); const verify = useCallback( debounce(name => { console.log(name); }, 200), [] ); return <input onChange={e => setUsername(e.target.value)} />; }

También necesita actualizar ligeramente su función de rebote, ya que no pasa los argumentos correctamente a la función de rebote.

 function debounce(func, wait, immediate) { var timeout; return (...args) => { <--- needs to use this `args` instead of the ones belonging to the enclosing scope var context = this; ...

manifestación

over 4 years ago · Santiago Trujillo Report

0

Sugiero algunos cambios.

1) Cada vez que realiza un cambio de estado, activa un renderizado. Cada render tiene sus propios accesorios y efectos. Entonces, su useEffect está generando una nueva función de rebote cada vez que actualiza el nombre de usuario. Este es un buen caso para useCallback ganchos para mantener la instancia de la función igual entre los renderizados, o posiblemente useRef tal vez - me quedo con useCallback yo mismo.

2) Separaría los controladores individuales en lugar de usar useEffect para activar su rebote: termina teniendo una larga lista de dependencias a medida que su componente crece y no es el mejor lugar para esto.

3) Su función de rebote no se ocupa de los parámetros. (Reemplacé con lodash.debouce, pero puede depurar su implementación)

4) Creo que aún desea actualizar el estado al presionar una tecla, pero solo ejecute su función denunciada cada x segundos

Ejemplo:

 import React, { useState, useCallback } from "react"; import "./styles.css"; import debounce from "lodash.debounce"; export default function App() { const [username, setUsername] = useState(''); const verify = useCallback( debounce(username => { console.log(`processing ${username}`); }, 1000), [] ); const handleUsernameChange = event => { setUsername(event.target.value); verify(event.target.value); }; return ( <div className="App"> <h1>Debounce</h1> <input type="text" value={username} onChange={handleUsernameChange} /> </div> ); }

MANIFESTACIÓN

Recomiendo encarecidamente leer esta gran publicación sobre useEffect y hooks.

over 4 years ago · Santiago Trujillo Report

0

Aquí hay una mejor manera de resolver esto;)

 export function useLazyEffect(effect: EffectCallback, deps: DependencyList = [], wait = 300) { const cleanUp = useRef<void | (() => void)>(); const effectRef = useRef<EffectCallback>(); const updatedEffect = useCallback(effect, deps); effectRef.current = updatedEffect; const lazyEffect = useCallback( _.debounce(() => { cleanUp.current = effectRef.current?.(); }, wait), [], ); useEffect(lazyEffect, deps); useEffect(() => { return () => { cleanUp.current instanceof Function ? cleanUp.current() : undefined; }; }, []); }
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!