簡體   English   中英

ReactJS - 如何使用 useEffect 獲取多個數據

[英]ReactJS - how to fetch multiple data with useEffect

我對反應useEffect ,現在我有一個函數可以在我的useEffect鈎子中獲取一些數據,使用加載狀態來管理組件渲染,然后使用該數據加載我的狀態組件,一切正常。

但是現在我必須實現另一個函數來獲取其他一些數據。

如何以最好的方式實現這一點? 我需要為另一個 fetch 函數創建另一個useEffect嗎?

這是我的代碼:

export default function Home() {
  const [ageOptions, setAgeOptions] = useState([])
  const [age, setAge] = useState('')
  const [loading, setLoading] = useState(false)

  // get age option from API
   useEffect(() => {
    setLoading(true)
    const fetchAgeOptions = () => {
     // transform the data to load properly in my react-select component
      function transform(data) {
        const options = data.map(function (row) {
          return { value: row.id, label: row.description, startAge: row.startAge, endAge: row.endAge }
        })
        setAgeOptions(options)
        setLoading(false)
      }
      api.get('someurl.com').then(response =>
        Object.values(response.data.rows)).then(data => transform(data))
    }
    fetchAgeOptions()
  }, [])


  return loading ? <div>Loading...</div> :
    <>
      <label>Age level</label>
      <Select
        value={age}
        options={ageOptions}
        placeholder="All"
        onChange={val => {
          setAge(val)
        }}
      />
    </>
}

您當前的 useEffect 只會在 mount 上運行(因為您在 use effect [] 的末尾添加了空括號)。 如果您計划僅調用此函數一次(掛載時),那么您可以將它放在同一個 useEffect 中。 如果你想在每次狀態更新時調用一個函數,那么你所要做的就是創建一個單獨的 useEffect 並將狀態作為依賴項。

useEffect(() => {

  }, ['variable-here-on-update-will-call-whatever-is-in-the-useEffect'])

這是我的一個例子:

//will run on componentDidMount
useEffect(() => {
  setError(false);
}, []);

//will run if error is updated in parent component
useEffect(() => {
  if (error && error.body) {
    setError(true);
  }
}, [error]);

我還建議您從 useEffect 中取出您的 'fetchAgeOptions' 函數(並在上面添加它),因為您無論如何都要調用它。 這樣它就不是 useEffect 的私有函數,它看起來更干凈。

您可能想要創建一個名為 useFetch 的自定義鈎子,其中包含 useEffect 和 useState,它應該返回狀態(初始、加載、錯誤和成功)和結果,然后僅當第一個效果具有正確的狀態時才調用第二個效果。

就像您可以多次使用 State Hook 一樣,您也可以使用多種效果。 這讓我們可以將不相關的邏輯分成不同的效果:

function FriendStatusWithCounter(props) {
  const [count, setCount] = useState(0);
  useEffect(() => {
    document.title = `You clicked ${count} times`;
  });

  const [isOnline, setIsOnline] = useState(null);
  useEffect(() => {
    function handleStatusChange(status) {
      setIsOnline(status.isOnline);
    }

    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
  });
  // ...
}

Hooks 讓我們根據代碼在做什么而不是生命周期方法名稱來拆分代碼。 React 將按照指定的順序應用組件使用的每個效果。

React Docs - Effect Hook https://reactjs.org/docs/hooks-effect.html

使用承諾所有


   useEffect(() => {
    setLoading(true)
    const fetchAgeOptions = () => {
     // transform the data to load properly in my react-select component
      function transform(data) {
        const options = data.map(function (row) {
          return { value: row.id, label: row.description, startAge: row.startAge, endAge: row.endAge }
        })
        setAgeOptions(options)
        setLoading(false)
      }
      api.get('someurl.com').then(response =>
        Object.values(response.data.rows)).then(data => transform(data))
    }
  const fetchAgeOptions = () => {
     // transform the data to load properly in my react-select component
      function transform(data) {
        const options = data.map(function (row) {
          return { value: row.id, label: row.description, startAge: row.startAge, endAge: row.endAge }
        })
        setAgeOptions(options)
        setLoading(false)
      }
      api.get('someurl.com').then(response =>
        Object.values(response.data.rows)).then(data => transform(data))
    }
    const fetchAgeOptions = () => {
     // transform the data to load properly in my react-select component
      function transform(data) {
        const options = data.map(function (row) {
          return { value: row.id, label: row.description, startAge: row.startAge, endAge: row.endAge }
        })
        setAgeOptions(options)
        setLoading(false)
      }
      api.get('someurl.com').then(response =>
        Object.values(response.data.rows)).then(data => transform(data))
    }

  Promise.all([fetchMethod1,fetchMethod2,fetchMethod3]).then(data=>{
// DATA IS AN ARRAY AND THEY ARE IN ORDER AS PLACED IN 
})
    
  }, [])

暫無
暫無

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

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