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

45
Views
event.target.value omitiendo el último carácter

He estado resolviendo este problema sin ningún progreso durante las últimas 2 horas, aquí está el código:

 export const useFetchAll = () => {
 const [searchResult, setSearchResult] = useState([]);
 const [loading, setLoading] = useState(false);
 const [searchItem, setSearchItem] = useState("");
 const [listToDisplay, setListToDisplay] = useState([]);

 // const debouncedSearch = useDebounce(searchItem, 300);

 const handleChange = (e) => {
 setSearchItem(e.target.value);

 if (searchItem === "") {
 setListToDisplay([]);
 } else {
 setListToDisplay(
 searchResult.filter((item) => {
 return item.name.toLowerCase().includes(searchItem.toLowerCase());
 })
 );
 }
 console.log(searchItem);
 };

 useEffect(() => {
 const searchRepo = async () => {
 setLoading(true);

 const { data } = await axios.get("https://api.github.com/repositories");
 setSearchResult(data);

 setLoading(false);
 };

 if (searchItem) searchRepo();
 }, [searchItem]);

el problema es que cuando ingreso caracteres en la entrada y configuro el estado en event.target.value, no selecciona el último carácter. aquí hay una imagen: ingrese la descripción de la imagen aquí

Por cierto, este es un gancho personalizado, devuelvo la función onchange aquí:

 
const HomePage = () => {
 const { searchResult, loading, searchItem, handleChange, listToDisplay } =
 useFetchAll();

y luego pasarlo como accesorio a un componente así:

 <Stack spacing={2}>
 <Search searchItem={searchItem} handleChange={handleChange} />
 </Stack>
 </Container>

¿alguna ayuda? gracias de antemano.

almost 4 years ago · Santiago Trujillo
2 answers
Answer question

0

Está manejando las searchResult de estado searchItem y searchResult como si su cambio de estado fuera síncrono (a través setSearchItem y setSearchResult ), ¡pero no lo es! Los setters de estado React son asincrónicos .

La devolución de llamada useEffect depende de la variable de estado searchItem . Ahora, cada vez que el usuario escriba algo, el estado cambiará, ese cambio activará una nueva representación del Componente y, una vez finalizada la representación, el side-effect (la devolución de llamada useEffect ) se ejecutará debido al ciclo de vida de los Componentes.

En nuestro caso, no queremos iniciar la solicitud de recuperación en el siguiente procesamiento, sino justo en el momento en que el usuario ingresa algo en el campo de entrada de búsqueda, es cuando se activa handleChange .

Para que el código funcione como se espera, necesitamos una refactorización más estructural.

Puedes deshacerte del useEffect y manejar el flujo a través del método handleChange :

 export const useFetchAll = () => {

 const [ loading, setLoading ] = useState( false );
 const [ searchItem, setSearchItem ] = useState( "" );
 const [ listToDisplay, setListToDisplay ] = useState( [] );

 const handleChange = async ( e ) => {

 const { value } = e.target;
 // Return early if the input is an empty string:
 setSearchItem( value );
 if ( value === "" ) {
 return setListToDisplay( [] );
 }
 setLoading( true );
 const { data } = await axios.get( "https://api.github.com/repositories" );
 setLoading( false );
 const valueLowercase = value.toLowerCase(); // Tiny optimization so that we don't run the toLowerCase operation on each iteration of the filter process below
 setListToDisplay(
 data.filter(({ name }) => name.toLowerCase().includes(valueLowercase))
 );
 };

 return {
 searchItem,
 handleChange,
 loading,
 listToDisplay,
 };
};
almost 4 years ago · Santiago Trujillo Report

0

la función utilizada para actualizar el valor del estado es asíncrona, por eso su variable de estado muestra el valor anterior y no el valor actualizado. He realizado algunos cambios, puede intentar ejecutar el siguiente código.

 const [searchResult, setSearchResult] = useState([]);
 const [loading, setLoading] = useState(false);
 const [searchItem, setSearchItem] = useState("");
 const [listToDisplay, setListToDisplay] = useState([]);

 // const debouncedSearch = useDebounce(searchItem, 300);

 const handleChange = (e) => {
 setSearchItem(e.target.value); // this sets value asyncronously 
 console.log("e.target.value :" + e.target.value); // event.target.value does not omitting last character
 console.log("searchItem :" + searchItem); // if we check the value then it is not set. it will update asyncronously 
 
 };

 const setList = async () => {
 if (searchItem === "") {
 setListToDisplay([]);
 } else {
 setListToDisplay(
 searchResult.filter((item) => {
 return item.name.toLowerCase().includes(searchItem.toLowerCase());
 })
 );
 }
 };


 const searchRepo = async () => { 
 const { data } = await axios.get("https://api.github.com/repositories");
 setSearchResult(data);
 setLoading(false);
 };

 // this useeffect execute its call back when searchItem changes a
 useEffect(() => {
 setList(); // called here to use previous value stored in 'searchResult' and display something ( uncomment it if you want to display only updated value )
 if (searchItem) searchRepo();
 }, [searchItem]);


 // this useeffect execute when axios set fetched data in 'searchResult' 
 useEffect(() => {
 setList(); 
 }, [searchResult]);


 // this useeffect execute when data is updated in 'listToDisplay'
 useEffect(() => {
 console.log("filtered Data") // final 'listToDisplay' will be availble here
 console.log(listToDisplay)
 }, [listToDisplay]);
almost 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!