如何在页面加载时获取数据,然后在按钮上单击以使用useEffect

时间:2019-08-15 07:21:47

标签: reactjs react-hooks

我正在尝试实现以下简单模式:

  • GET列表
  • 输入新项目,保存
  • 发出POST请求
  • 提出新的GET请求以获取更新的数据

here中的代码开始,

const useApi = () => {
  const [data, setData] = useState({ hits: [] });
  const [url, setUrl] = useState(
    'https://hn.algolia.com/api/v1/search?query=redux',
  );

  useEffect(() => {
    const fetchData = async () => {
        const result = await axios(url);
        setData(result.data);
    };

    fetchData();
  }, [url]);

  return [{ data }, setUrl];
}

很容易在页面装载上进行初始获取

  const [{ data }, doFetch] = useDataApi(
    'https://hn.algolia.com/api/v1/search?query=redux',
    { hits: [] },
  );

但是我不了解的是如何“刷新”数据。由于没有状态变量确定是否应重新运行该挂钩,因此如何在单击按钮时手动调用该挂钩?

3 个答案:

答案 0 :(得分:2)

使用类似简单计数机制的单独变量:

SELECT *
FROM Cables C
LEFT JOIN Fibres F on C.OID = F.OID1 or C.OID = F.OID2


SELECT *
FROM Cables C
LEFT JOIN Fibres F  on C.OID = F.OID1
LEFT JOIN Fibres F2 on C.OID = F2.OID2

然后使用“ count”作为有状态变量以及网址(如果用户搜索了其他内容):

const [count, setCount] = useState(0);

<button onClick={() => setCount(count + 1)} />

答案 1 :(得分:2)

这是另一种方法。也许有更好的方法,但是在这种情况下,它似乎可以工作。

您可以从fetchData返回useDataApi,然后在onClick处理程序中使用它,并在useRef的帮助下查找URL更改。为此,您应该将fetchData移到useEffect之外,并用useCallback

包裹起来
  ...
  const fetchData = useCallback(
    async () => {
      setIsError(false);
      setIsLoading(true);

      try {
        const result = await axios(url);
        setData(result.data);
      } catch (error) {
        setIsError(true);
      }

      setIsLoading(false);
    },
    [url],
  );


  useEffect(() => {
    fetchData();
  }, [url, fetchData]); // add fetchData here as a second dependency

  return [{ data, isLoading, isError }, setUrl, fetchData]; // add fetchData here as the third returned variable.
};

然后在您的应用中,您可以使用引用来检查URL是否未更改:

function App() {
  const [query, setQuery] = useState('redux');
  const latestQuery = useRef(query); // define the ref
  const [{ data, isLoading, isError }, doFetch, fetchData] = useDataApi(
    'https://hn.algolia.com/api/v1/search?query=redux',
    { hits: [] },
  );

  return (
    <Fragment>
      <form
        onSubmit={event => {
          // check the query change
          if (latestQuery.current === query) {
            fetchData();
          }
          doFetch(
            `https://hn.algolia.com/api/v1/search?query=${query}`,
          );

          // set current query to the ref value
          latestQuery.current = query;

          event.preventDefault();
        }}
      >
      .....

我不太确定这是一个更好的解决方案,因为我自己也在学习钩子:)

答案 2 :(得分:0)

我认为,如果在发出初始api请求之后调度一个操作以获取可用的最新数据,则可以简化您描述的流程。随后,应在每次安装组件时发出请求,这样您的组件将不负责确保其具有最新数据。该流程类似于:

1)GET列表

2)输入新项目,保存

3)提出POST请求

4)有一个操作(在消费组件之外)处理响应,如果成功,则dispatch采取行动以重新启动最初的GET列表调用,否则,调用处理错误。