onChange 是延迟的一个字符 - Hooks

IT技术 javascript reactjs asynchronous
2021-05-18 22:10:49

我是 React 和 Hooks 的新手。

我创建了一个简单的搜索栏,用户可以在其中键入一些文本。

但是,如果我console.log在 之后的状态onChange,它总是落后一个字符。

例如:如果我输入“pizza”,则console.log显示“pizz”

我的组件

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>
);
}

经过一些研究(onChange 事件以 1 个字符延迟更新状态),我明白这setState 是异步的。

所以我尝试了不同的解决方案来使它工作:

1) 解决方案一

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

但我有同样的问题(最后一个字符没有被捕获)

2) 方案二

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

但我得到 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 component body with useEffect().

3) 方案三

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

但我有同样的问题(最后一个字符没有被捕获)

1个回答

如您所知,useState 是异步函数。当您在功能组件中使用 useState 时,您必须在 useEffect 中处理变量才能看到变量的变化,如下所示:

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} />;
};