簡體   English   中英

對useEffect感到困惑

[英]Confused about useEffect

我正在構建我的第一個Custom React Hook,並對我認為代碼的簡單方面感到困惑:

export const useFetch = (url, options) => {
  const [data, setData] = useState();
  const [loading, setLoading] = useState(true);
  const { app } = useContext(AppContext);
  console.log('** Inside useFetch: options = ', options);

  useEffect(() => {
    console.log('**** Inside useEffect: options = ', options);
    const fetchData = async function() {
      try {
        setLoading(true);
        const response = await axios.get(url, options);
        if (response.status === 200) {
          setData(response.data);
        }
      } catch (error) {
        throw error;
      } finally {
        setLoading(false);
      }
    };
    fetchData();
  }, []);

  return { loading, data };
};

我將useFetch傳遞給兩個參數:一個URL和一個headers對象,其中包含一個如下所示的AWS Cognito授權密鑰: Authorization: eyJraWQiOiJVNW... (為簡潔起見而縮短)

當我執行此操作時, options對象的確存在於useFetch內,但在useEffect構造內為空。 但是,在兩種情況下都正確填充了url字符串。

這對我來說毫無意義。 可能有人知道為什么會這樣嗎?

在代碼的實現下方,表明該代碼可以按預期工作。

異步/等待已轉換為Promise,但應具有相同的行為。

輸出“內部使用提取” 3次:

  1. 掛載( useEffect(()=>..., []
  2. 第一次狀態更改后( setLoading(true)
  3. 在第二個狀態更改后( setLoading(false)

並在安裝時輸出1次“內部使用效果”useEffect(()=>..., []

由於這種方式對您不起作用,這可能意味着在安裝組件時,選項尚不可用。

在說出將選項作為依賴項放置時,您會對其進行確認,兩次調用useEffect時,第一次獲取失敗(很可能是因為缺少選項)。

我很確定您會使用自定義鈎子在組件的父級中找到選項的問題。

 const axios = { get: (url, options) => { return new Promise(resolve => setTimeout(() => resolve({ status: 200, data: 'Hello World' }), 2000)); } }; const AppContext = React.createContext({ app: null }); const useFetch = (url, options) => { const [data, setData] = React.useState(); const [loading, setLoading] = React.useState(true); const { app } = React.useContext(AppContext); console.log('** Inside useFetch: options = ', JSON.stringify(options)); React.useEffect(() => { console.log('**** Inside useEffect: options = ', JSON.stringify(options)); const fetchData = function () { setLoading(true); const response = axios.get(url, options) .then(response => { if (response.status === 200) { setData(response.data); } setLoading(false); }) .catch(error => { setLoading(false); throw error; }); }; fetchData(); }, []); return { loading, data }; }; const App = ({url, options}) => { const { loading, data } = useFetch(url, options); return ( <div style={{ display: 'flex', background: 'red', fontSize: '20px', fontWeight: 'bold', justifyContent: 'center', alignItems: 'center', width: 300, height: 60, margin: 5 }} > {loading ? 'Loading...' : data} </div> ); }; ReactDOM.render( <App url="https://www.dummy-url.com" options={{ headers: { Authorization: 'eyJraWQiOiJVNW...' } }} />, document.getElementById('root') ); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script> <div id="root" /> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM