首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Reactjs:如何在设置变量后调用useFetch

Reactjs:如何在设置变量后调用useFetch
EN

Stack Overflow用户
提问于 2020-10-21 08:34:09
回答 2查看 284关注 0票数 0

我正在编写一个reactjs网络应用程序,在这里我首先需要加载一个度假村列表,然后,在用户选择其中一个之后,加载度假村的所有细节。

这是我的useFetch函数:

代码语言:javascript
复制
const useFetch = (url, options) => {
  const [response, setResponse] = React.useState(null);
  const [error, setError] = React.useState(null);
  const [isLoading, setIsLoading] = React.useState(false);
  React.useEffect(() => {
    (async () => {
      setIsLoading(true);
      try {
        const res = await fetch(url, options);
        const json = await res.json();
        setResponse(json);
        setIsLoading(false);
      } catch (error) {
        setError(error);
        setIsLoading(false);
      }
    })();
  }, []);
  return [ response, error, isLoading ];
};

在我的组件中,我使用它检索度假村列表,没有任何问题:

代码语言:javascript
复制
function App() {
  const [resorts, resortsIsLoading, resortsError] = useFetch(config.API_URL_GET_RESORTS);
  const [resortId, setResortId] = useState(null);

  const handleChangeResort = (event) => {
    const id = event.target.value;
    setResortId(id);
  };

  return (
    <>
      <Select
        labelId="resort-label"
        id="resort"
        label="resort"
        value={resort ? resort.id : ""}
        onChange={handleChangeResort}
      >
        {resorts.length ? (
          resorts.map(c => (
            <MenuItem key={c.id} value={c.id}>
              {c.name}
            </MenuItem>
          ))
        ) : (
          <MenuItem key={0} value={""}>
            <em>loading resorts list...</em>
          </MenuItem>
        )}
      </Select>
    </>
  )}
}

问题是,在第一个useFetch调用之后,我无法添加一个useFetch来获取所选的度假胜地详细信息:

代码语言:javascript
复制
  const [resorts, resortsIsLoading, resortsError] = useFetch(config.API_URL_GET_RESORTS);
  const [resort, resortIsLoading, resortError] = useFetch(config.API_URL_GET_RESORT, {id: resortId});

因为最初我还没有resortId。

我需要这样的东西:

代码语言:javascript
复制
  useEffect(() => {
    if (resortId !== null) {
      const [resort, resortIsLoading, resortError] = useFetch(config.API_URL_GET_RESORT, {id: resortId});
    }
  }, [resortId]);

但是useEffect()内部不能用钩子.

我应该采用什么解决方案来使用useFetch()逻辑(我非常喜欢它,因为它隐藏了从邮件应用程序逻辑中获取的细节)的条件方式(即:在resortId可用之后)?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-10-21 08:55:41

钩子可以提供一个函数来获取/重新获取数据:

代码语言:javascript
复制
const useFetch = (url, options) => {
  const [response, setResponse] = React.useState(null);
  const [error, setError] = React.useState(null);
  const [isLoading, setIsLoading] = React.useState(false);

  const fetchData = async (resortId) => {
    setIsLoading(true);

    try {
      const res = await fetch(url, {id: resortId});
      const json = await res.json();
      setResponse(json);
      setIsLoading(false);
    } catch (error) {
      setError(error);
      setIsLoading(false);
    }
  }

  return [
    response, 
    error, 
    isLoading,
    fetchData
  ];
};

然后,只要您想更新搜索,就可以调用fetchData:

代码语言:javascript
复制
const App = () => {
  const [resort, resortIsLoading, resortError, fetchResort] = useFetch(config.API_URL_GET_RESORT);


 const handleChangeResort = (event) => {
    const id = event.target.value;
    fetchResort(id);
 };

  return (
    <>
      <Select
        labelId="resort-label"
        id="resort"
        label="resort"
        value={resort ? resort.id : ""}
        onChange={handleChangeResort}
      >
        {resorts.length ? (
          resorts.map(c => (
            <MenuItem key={c.id} value={c.id}>
              {c.name}
            </MenuItem>
          ))
        ) : (
          <MenuItem key={0} value={""}>
            <em>loading resorts list...</em>
          </MenuItem>
        )}
      </Select>
    </>
  )}
}
票数 2
EN

Stack Overflow用户

发布于 2020-10-21 09:13:09

我会这样做:

代码语言:javascript
复制
const useFetch = (url) => {
  const [state, setState] = React.useState([null, false, null]);

  const fetchData = async (options) => {
    setState([null, true, null]);

    try {
      const res = await fetch(url, options);
      const json = await res.json();
      setState([json, false, null]);
    } catch (error) {
      setState([null, false, error]);
    }
  }

  return [
    ...state, // response, loading, error
    fetchData
  ];
};

然后,你可以用:

代码语言:javascript
复制
const [resorts, resortsIsLoading, resortsError, fetchResorts] = useFetch(config.API_URL_GET_RESORTS);
const [resort, resortIsLoading, resortError, fetchResort] = useFetch(config.API_URL_GET_RESORT);

useEffect(() => {
  fetchResorts()
}, [])
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64459774

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档