根据其他钩子的结果对钩子做出反应

时间:2019-08-12 07:00:16

标签: reactjs react-hooks

我有一个自定义钩子useWebApi,该钩子可以调用网络api并返回api结果。

function useWebApi(method, url) {
  const [fetching, setFetching] = useState(true);
  const [result, setResult] = useState(null);
  useEffect(() => {
    axios[method](url).then(res => {
      setFetching(false);
      setResult(res);
    })
  }, [url]);
  return [fetching, result];
}

,我想做的事情是,获取url1,如果获取了url1,则获取url2。这两个API是非独立的,url2仅在url1完成提取后才能调用。 所以我写下面的代码

const url1 = '/login';
const url2 = '/getMyUserInfo';
function App() {
  const [fetching1, result1] = useWebApi('get', url1);
  if (result1) {
    const [fetching2, result2] = useWebApi('get', url2);
  }

  return (
    <div>
    {result1}
    {result2}
    </div>
  )
}

但是在if语句中不能调用hook,所以我将其更改为

const url1 = '/login';
const url2 = '/getMyUserInfo';
function App() {
  const [fetching1, result1] = useWebApi('get', url1);
  useEffect(() => {
    if (result1) {
      const [fetching2, result2] = useWebApi('get', url2);
    }
  }, [result1])

  return (
    <div>
    {result1}
    {result2}
    </div>
  )
}

但是,仍然存在问题,我无法渲染result2,因为它位于嵌套作用域内,那么如何解决呢?

3 个答案:

答案 0 :(得分:3)

您可以做的是公开一个doFetch方法,等等,该方法将允许手动调用该挂钩。

function useWebApi(method, url) {
  const [fetching, setFetching] = useState(true);
  const [result, setResult] = useState(null);

  const doFetch = useCallback((fetchUrl = url) => {
    axios[method](fetchUrl).then(res => {
      setFetching(false);
      setResult(res);
    })
  }, [method, url])

  useEffect(() => {
    if (url) {
      doFetch();
    }
  }, [doFetch]);

  return [fetching, result, doFetch];
}
function App() {
  const [fetching1, result1, doFetch1] = useWebApi('get', url1);
  const [fetching2, result2, doFetch2] = useWebApi('get');

  useEffect(() => {
    if (result1) {
      doFetch2(url2);
    }
  }, [result1])

  return (
    <div>
    {result1}
    {result2}
    </div>
  )
}

答案 1 :(得分:0)

如果第二个调用不依赖于第一个调用的结果值(即它们是两个独立的GET请求),则继续进行操作,并按照钩子的预期在顶层调用它们,并仅在结果为一个时才有选择地呈现结果二存在。

function App() {
  const [fetching1, result1] = useWebApi('get', url1);
  const [fetching2, result2] = useWebApi('get', url2);

  return (
    <div>
      {result1}
      {result1 ? result2 : null}
    </div>
  )
}

答案 2 :(得分:0)

您也许可以将条件移到钩子中

function useWebApi(method, url, flag = true) {
  const [fetching, setFetching] = useState(true);
  const [result, setResult] = useState(null);
  useEffect(() => {
    if(flag) {
        axios[method](url).then(res => {
          setFetching(false);
          setResult(res);
        })
    }
  }, [url, flag]);
  return [fetching, result];
}


function App() {
  const [fetching1, result1] = useWebApi('get', url1);
  const [fetching2, result2] = useWebApi('get', url2, !!result1);

  return (
    <div>
    {result1}
    {result2}
    </div>
  )
}