0

在一个简单的搜索组件上尝试反应钩子。这个想法很简单:用户键入符号,每个键入的符号都会启动 api 查询。
为了实现这一点,我在下面的代码中有useState钩子useCallback


const Search = () => {
  const [query, setQuery] = useState("");
  const sendRequest = useCallback(() => {
    console.log('sendRequest ', query);
  }, [query]);

  return (
    <div>
      <input
        type="text"
        value={query}
        placeholder="Search"
        onChange={e => {
          console.log('onChange ', e.target.value);
          setQuery(e.target.value);
          sendRequest();
        }}
      />
    </div>
}

结果是该sendRequest方法总是获得以前版本的query.

onChange q
sendRequest 
onChange qu
sendRequest q
onChange que
sendRequest qu

这是为什么?我认为这不是挂钩的使用方式,但我无法从文档中弄清楚。

4

3 回答 3

1

嘿兄弟,你可以试试这个实现,它的工作原理和你期望的一样

const [query, setQuery] = useState("");
  const sendRequest = e => {
    setQuery(e);
    console.log('sendRequest ', e);
  };

  return (
    <div>
      <input
        type="text"
        value={query}
        placeholder="Search"
        onChange={e => {
          console.log('onChange ', e.target.value);
          sendRequest(e.target.value);
        }}
      />
    </div>)
于 2019-08-10T11:09:27.087 回答
1

setState 是异步的!在您发送 sendRequest 时,本地状态不会更新,因为它是异步的,需要一些时间来设置。

您应该将字符串作为参数提供给函数或 useEffect 并监听查询的变化。

用 useEffect 交换 useCallback 并删除 onChange 中的调用应该可以工作。

const Search = () => {
  const [query, setQuery] = useState("");

  useEffect(() => {
    console.log('sendRequest ', query);
  }, [query]);

  return (
    <div>
      <input
        type="text"
        value={query}
        placeholder="Search"
        onChange={e => {
          setQuery(e.target.value);
        }}
      />
    </div>
}
于 2019-08-10T11:05:56.307 回答
1

使用 useEffect 代替 useCallback。useEffect 在查询更改时触发您的回调函数。

useEffect(() => { console.log(query) }, [query])

于 2019-08-10T11:08:13.497 回答