如何在重新渲染时更新API调用?

时间:2019-04-22 01:48:12

标签: reactjs state react-hooks

我正在自学React Hooks,我想在用户在搜索框中键入内容时更新API调用。某种实时搜索。我已经收集到该事件仅在页面加载时触发,但是我该如何解决呢?

此处的示例:https://codesandbox.io/s/6x1xp57zmk

import React, {useState, useEffect} from 'react';

function App() {

  const [cardNames, setCardName] = useState([])

  const rezCards = async () => {
    //const rez = await fetch('https://api.scryfall.com/cards?page=3')
    const rez = await fetch ('https://api.scryfall.com/catalog/card-names')
    const json = await rez.json()
    setCardName(json.data)
  }

  useEffect(() => {
    rezCards()
  },[])

  return <ul>{cardNames
    .slice(0,50)
    .map(
      (cardName) => {
        return <li key={cardName}>{cardName}</li>
      }
    )}</ul>
}

export default App

2 个答案:

答案 0 :(得分:0)

问题可能在这里:

useEffect(() => {
    rezCards()
},[])

您将第二个参数留为空数组,这导致useEffect仅在组件装入时运行一次,与componentDidMount相同。

如果希望在状态更改时触发useEffect,则可以将状态添加为挂钩的依赖项,例如

const { callThisEffectWhenThisValueIsChanged, changeValue } = useState('');

useEffect(() => {
    // Do anything with here, for eg call APIs
},[callThisEffectWhenThisValueIsChanged])

changeValue(newValue);

因此,在您的CodeSandbox代码中,您所需要做的就是在依赖项中添加searchInput,并且只要更改搜索输入,它将再次调用该钩子。

useEffect(() => {
    rezCards();
}, [searchInput]);

永远记住,只要您的效果使用任何状态,就需要添加该状态作为效果挂钩的依赖项

您可以在React Hook doc

中找到更多信息。

答案 1 :(得分:0)

有些事情你应该看看。为了防止在搜索框上键入多个api调用,请使用一种名为debounce的技术,您可以使用react钩子来实现此目的:

function useDebounce(value, delay) {
  const [debouncedValue, setDebouncedValue] = useState(value);

  useEffect(
    () => {
      const handler = setTimeout(() => {
        setDebouncedValue(value);
      }, delay);

      return () => {
        clearTimeout(handler);
      };
    },
    [value, delay],
  );

  return debouncedValue;
}

function App() {

  const debouncedInput = useDebounce(searchInputValue, 300);
  useEffect(() => {
    rezCards()
  },[debouncedInput])
}