最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - onChange is one character on delay - Hooks - Stack Overflow

programmeradmin2浏览0评论

I am new to React and Hooks.

I create a simple search bar where the user can type some text.

However, if I console.log the state after the onChange, it is always one character behind.

For example: If I type "pizza", the console.log shows "pizz"

My ponent

export default function SearchBar({handlerSearchBar}) {
    const classes = useStyles();
    const [searchBarQuery, setSearchBarQuery] = React.useState([""])

function handleChange(event){
    setSearchBarQuery(event.target.value)
    // handlerSearchBar(searchBarQuery)
    console.log(searchBarQuery)
}



return (
    <form className={classes.container} noValidate autoComplete="off">
        <TextField
            id="standard-full-width"
            label="Searchbar"
            style={{ marginLeft: 40, marginRight: 40 }}
            placeholder="Write your query"
            // helperText="The results will appear below!"
            fullWidth
            margin="normal"
            InputLabelProps={{
                shrink: true,
            }}
            onChange={handleChange}
        />
    </form>
);
}

After some research (onChange event updates state with 1 character delay), I understand that setState is asynchronous.

So I tried varies solutions to make it work:

1) Solution One

function handleChange(event) {
    let text = event.target.value;
    setSearchBarQuery({
        text: text
    });
    console.log(searchBarQuery)
}

But I have the same problem (last character is not captured)

2) Solution Two

function handleChange(event) {
    let text = event.target.value;
    setSearchBarQuery({
        text: text
    }, ()=>console.log(searchBarQuery));
}

But I get Warning: State updates from the useState() and useReducer() Hooks don't support the second callback argument. To execute a side effect after rendering, declare it in the ponent body with useEffect().

3) Solution Three

   async function handleChange(event) {
        await setSearchBarQuery({text: event.target.value});
        console.log(searchBarQuery)
    }

But I have the same problem (last character is not captured)

I am new to React and Hooks.

I create a simple search bar where the user can type some text.

However, if I console.log the state after the onChange, it is always one character behind.

For example: If I type "pizza", the console.log shows "pizz"

My ponent

export default function SearchBar({handlerSearchBar}) {
    const classes = useStyles();
    const [searchBarQuery, setSearchBarQuery] = React.useState([""])

function handleChange(event){
    setSearchBarQuery(event.target.value)
    // handlerSearchBar(searchBarQuery)
    console.log(searchBarQuery)
}



return (
    <form className={classes.container} noValidate autoComplete="off">
        <TextField
            id="standard-full-width"
            label="Searchbar"
            style={{ marginLeft: 40, marginRight: 40 }}
            placeholder="Write your query"
            // helperText="The results will appear below!"
            fullWidth
            margin="normal"
            InputLabelProps={{
                shrink: true,
            }}
            onChange={handleChange}
        />
    </form>
);
}

After some research (onChange event updates state with 1 character delay), I understand that setState is asynchronous.

So I tried varies solutions to make it work:

1) Solution One

function handleChange(event) {
    let text = event.target.value;
    setSearchBarQuery({
        text: text
    });
    console.log(searchBarQuery)
}

But I have the same problem (last character is not captured)

2) Solution Two

function handleChange(event) {
    let text = event.target.value;
    setSearchBarQuery({
        text: text
    }, ()=>console.log(searchBarQuery));
}

But I get Warning: State updates from the useState() and useReducer() Hooks don't support the second callback argument. To execute a side effect after rendering, declare it in the ponent body with useEffect().

3) Solution Three

   async function handleChange(event) {
        await setSearchBarQuery({text: event.target.value});
        console.log(searchBarQuery)
    }

But I have the same problem (last character is not captured)

Share Improve this question asked Nov 16, 2019 at 3:19 MagofocoMagofoco 5,4967 gold badges43 silver badges87 bronze badges 1
  • Your state updates correctly, just not where you want to see, move your console.log to useEffect hook, and you get the correct result. Your second solution is correct. – thelonglqd Commented Nov 16, 2019 at 3:58
Add a ment  | 

1 Answer 1

Reset to default 4

As you know, useState is async function. When you use useState inside functional Component, you have to handle variable in useEffect to see change of variable like this:

const App = () => {
  const [search, setSearch] = useState("");
  const onChange = e => {
    e.persist();
    setSearch(e.target.value);
  };

  useEffect(() => {
    console.log("Search message inside useEffect: ", search);
  }, [search]);

  return <input onChange={onChange} />;
};
发布评论

评论列表(0)

  1. 暂无评论