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

时间:2020-01-29 14:45:03

标签: javascript reactjs

我现在还很陌生,现在我有一个函数可以在useEffect挂钩中获取一些数据,使用加载状态来管理组件渲染,然后使用该数据加载状态组件,一切工作正常。

但是现在我必须实现另一个功能来获取其他数据。

如何以最佳方式实现这一目标?我是否需要为另一个提取功能创建另一个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)
        }}
      />
    </>
}

4 个答案:

答案 0 :(得分:0)

您当前的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的私有函数,并且看起来会更干净。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

就像您可以多次使用 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

答案 3 :(得分:0)

全部使用承诺


   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 
})
    
  }, [])