He estado implementando una función de búsqueda a medida que escribe y me gustaría tener la función de search que maneja mis llamadas API para que sean eliminadas. Lo cual funciona bien si solo llamo a la función debounced_search dentro del controlador de eventos, pero también necesito actualizar el valor de entrada, lo que debería suceder de inmediato.
Mi problema ahora es que tan pronto como agrego setInput(newInputValue); para el controlador de eventos, la función de búsqueda ya no se rebota, pero se llama inmediatamente en cada cambio, aunque estoy usando la versión rebotada.
¿Por qué sucede eso? ¿Y cómo soluciono esto?
Gracias.
import React from 'react' import Autocomplete from '@mui/material/Autocomplete'; import { selectClasses, TextField } from '@mui/material'; import debounce from 'lodash/debounce'; function Searchbar() { const [options, setOptions] = React.useState([]); const [input, setInput] = React.useState(""); const search = (event, newInputValue) => { console.log("Debounced Called") } const debounced_search = debounce(search, 500) return (<Autocomplete id="free-solo" freeSolo renderInput={(params) => <TextField {...params} label="Test" />} inputValue={input} options={options} onInputChange={function (event, newInputValue) { debounced_search(event, newInputValue); setInput(newInputValue); console.log("Input Changed") }} />) } export default SearchbarLa razón por la que esto no funciona para usted es que el componente de la función se llama una y otra vez cada vez que hay un cambio de estado, lo que significa que todo lo que contiene se vuelve a ejecutar cada vez, incluida su llamada a debounce() . Para lidiar con este problema, React proporciona un gancho useCallback() :
const debounced_search = useCallback(debounce((event, newInputValue) => { console.log("Debounced Called") }, 500), []) Tenga en cuenta que incluí la función de search aquí porque tampoco es necesario volver a crearla en cada renderizado.
Esto es trabajo para mí:
índice.js
import React, { StrictMode } from "react"; import ReactDOM from "react-dom"; import App from "./App"; const rootElement = document.getElementById("root"); ReactDOM.render(<App />, rootElement);Aplicación.js
import React from "react"; import debounce from "@icaruk/debounce"; export default function App() { const [input, setInput] = React.useState(""); const search = (input) => { console.log(`Debounced Called with ${input}`); }; return ( <input id="free-solo" value={input} onChange={function (event) { const value = event.target.value; debounce(1000, () => search(value)); setInput(value); console.log(`Input Changed to ${value}`); }} /> ); } Aquí está la caja de arena:
https://codesandbox.io/s/blissful-water-gojli?file=/src/App.js
Si tiene alguna pregunta sobre el código, no dude en preguntar, no puse ningún comentario, pero tal vez algo necesite una explicación.