简体   繁体   English

ReactJS - 如何使用 useEffect 获取多个数据

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

I'm fairly new to react, right now I have a function that is fetching some data in my useEffect hook, using a loading state to manage component rendering and then loading my state component with that data, everything is working fine.我对反应useEffect ,现在我有一个函数可以在我的useEffect钩子中获取一些数据,使用加载状态来管理组件渲染,然后使用该数据加载我的状态组件,一切正常。

But now I have to implement another function to fetch some other data.但是现在我必须实现另一个函数来获取其他一些数据。

How can this be implemented in the best way possible?如何以最好的方式实现这一点? Do I need to create another useEffect for another fetch function?我需要为另一个 fetch 函数创建另一个useEffect吗?

Here is my code:这是我的代码:

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)
        }}
      />
    </>
}

Your current useEffect will only run on mount (because you added the empty brackets at the end of the use effect []).您当前的 useEffect 只会在 mount 上运行(因为您在 use effect [] 的末尾添加了空括号)。 If you are planning on only calling this function one time (on mount) then you can put it in the same useEffect.如果您计划仅调用此函数一次(挂载时),那么您可以将它放在同一个 useEffect 中。 If you want to call a function every time the state of something updates then all you have to do is make a separate useEffect with the state as a dependency.如果你想在每次状态更新时调用一个函数,那么你所要做的就是创建一个单独的 useEffect 并将状态作为依赖项。

useEffect(() => {

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

Here is an example on mine:这是我的一个例子:

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

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

I would also recommend taking out your 'fetchAgeOptions' function from the useEffect (and add it above) as you are calling to it anyways.我还建议您从 useEffect 中取出您的 'fetchAgeOptions' 函数(并在上面添加它),因为您无论如何都要调用它。 This way it is not a private function to the useEffect and it will look cleaner.这样它就不是 useEffect 的私有函数,它看起来更干净。

您可能想要创建一个名为 useFetch 的自定义钩子,其中包含 useEffect 和 useState,它应该返回状态(初始、加载、错误和成功)和结果,然后仅当第一个效果具有正确的状态时才调用第二个效果。

Just like you can use the State Hook more than once, you can also use several effects.就像您可以多次使用 State Hook 一样,您也可以使用多种效果。 This lets us separate unrelated logic into different effects:这让我们可以将不相关的逻辑分成不同的效果:

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 let us split the code based on what it is doing rather than a lifecycle method name. Hooks 让我们根据代码在做什么而不是生命周期方法名称来拆分代码。 React will apply every effect used by the component, in the order they were specified. React 将按照指定的顺序应用组件使用的每个效果。

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

Use a promise all使用承诺所有


   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