Home > Enterprise >  Last letter not getting set while onChange event
Last letter not getting set while onChange event

Time:12-07

I'm trying to write a function for a live search filter, this is what I have for doing that:

const [values, setValues] = useState({
    text: ''
});

<Input name="text" onChange={(e) => handleChange(e)} type={'text'} className="form-control"></Input>

const handleChange = async e=>{
    const {name, value} = e.target;

    await setValues({
        ...values,
        [name]: value
    });

    console.log(values);


    CallAPIWithSearchText(value.text);
}

The main problem is that for example; if I type "hello" what is stored in my const is "hell" and if I remove all text I'm getting "h" instead of null/empty string.

What can I do to fix my code?

CodePudding user response:

In React state updates may be asynchronous, so you can use the effect hook to solve this problem.

Every time your state changes, the callback in the effect hook runs after the render:

<div id="root"></div><script src="https://unpkg.com/[email protected]/umd/react.development.js"></script><script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script><script src="https://unpkg.com/@babel/[email protected]/babel.min.js"></script>
<script type="text/babel" data-type="module" data-presets="react">

const {useEffect, useState} = React;

function CallAPIWithSearchText (text) {
  console.log('API called with', text);
}

function Example () {
  const [values, setValues] = useState({text: ''});

  const handleChange = async e => {
    const {value} = e.target;
    setValues({
      ...values,
      text: value,
    });
  };

  useEffect(() => {
    console.log(values);
    const {text} = values;
    if (text) CallAPIWithSearchText(text);
  }, [values]);

  return (
    <input
      name="text"
      onChange={handleChange}
      type={'text'}
      className="form-control"
      value={values.text}
    ></input>
  );
}

ReactDOM.render(<Example />, document.getElementById('root'));

</script>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

The problem here is with your setValues function. It doesn't return a Promise. So, you can't use async-await with it.

What can you can do is, use the useEffect hook like below:

import React, {useState, useEffect} from 'react' //Import the useEffect hook.

useEffect(()=>{
  //This function will run every time the value of values state changes.
  console.log(values); //Will give you the updated value of values state.
  CallAPIWithSearchText(value.text); // Call your api method
  //Do some other stuff
}, [values])

const CallAPIWithSearchText = (text) => {
  //Use text as per your need.
  if(text === '') // Show all results
  else
    //Show results as per text
}

const handleChange = e => {
    const {name, value} = e.target;

    setValues({ //No need to use await
        ...values,
        [name]: value
    });
}
  • Related