Asked Aug 3rd, 10:28 AM 72 0 2
  • 72 0 2
+3

Cách cải thiện về loading trong Reactjs?

Share
  • 72 0 2

Chào các bạn, mình đang tập tành làm reactjs thì mình có đang làm phần loading khi click vào các button hoặc có action async nào đấy. Phần này thì ở mỗi component cần hiển thị icon loading thì mình sẽ có 1 state cho component đấy để handle việc có hiển thị loading hay không thì không biết mọi người kinh nghiệm thực tế nhiều sẽ xử lý cái loading cho từng button / action này như nào nhỉ?

2 ANSWERS


Answered Aug 3rd, 1:45 PM
+2

Cách đơn giản nhất để áp dụng loading như bạn muốn thì bạn chỉ cần tạo thêm một biến boolean chứa trạng thái loading mà thôi. Khi nào bạn thực hiện các async action thì bạn set biến này về true, ngược lại khi xong thì trả vê false:

const App = () => {
  const [isLoading, setIsLoading] = useState(false)
  
  async function handleLoadData() {
    try {
      setIsLoading(true);
      
      // Main logic
    } catch (error) {
      // Handle error
    } finally {
      setIsLoading(false);
    }
  }

  return (
    isLoading
    ? <SpinIcon />
    : <ListItem />
  )
}

Còn nếu trường hợp bạn muốn làm chi tiết hơn và đem đến UI tốt nhất cho từng trạng thái thì bạn nên áp dụng theo kiểu status như bên dưới.

const LOADING = 'LOADING';
const SUCCESS = 'SUCCESS';
const ERROR = 'ERROR';

const App = () => {
  const [status, setStatus] = useState(SUCCESS)
  
  async function handleLoadData() {
    try {
      setStatus(LOADING );
      // Main logic
      setStatus(SUCCESS);
    } catch (error) {
      setStatus(ERROR)
      // Handle error
    }
  }

  function renderData() {
    switch (status) {
      case LOADING:
        return <LoadingUI />
      case SUCCESS :
        return <ListItem />
      default:
        return <ErrorUI />
    }
  }

  return (
      {renderData()}
  )
}
Share
Avatar Nguyen Tuan Anh @TuanAnh9996
Aug 3rd, 2:16 PM

Hiện tại thì mình đang làm như này rồi, nhưng khi mình làm như này thì ở các component khác nhau thì mình cần có state khác nhau để lưu việc loading ấy nên mình đang thắc mắc là không biết làm thực tế người ta có làm như vậy không hay sẽ dùng cách khác tối ưu hơn

0
| Reply
Share
Aug 4th, 4:44 AM

@TuanAnh9996 như thế thì bạn có thể tạo thành một custom hook trả về 2 giá trị status và setStatus để dùng lại ở nhiều chỗ thôi

0
| Reply
Share
Answered Aug 3rd, 5:48 PM
+2

Vì việc load data đều xuất phát từ call api nên có thể dùng hooks để tóm gọn code call api gắn với trạng thái loading của lần call api đó

// hooks/useGetData.tsx
import { useEffect, useState } from 'react';
...

const useGetData = (
  endpoint,
  params?,
  successCallback?: () => void,
  failCallback?: () => void,
) => {
  const [loading, setLoading] = useState<boolean>(false);
  const [data, setData] = useState<unknown>();

  useEffect(() => {
    const fetchData = async () => {
      setLoading(true);
        try {
          const response = await axios.get(endpoint, params) // function call api ở đây
          setData(response.data)
          if (successCallback) successCallback(response.data);
        } catch(e) {
          // throw
          if (failCallback) failCallback();
        } .finally{
          setLoading(false);
        }
     }
    fetchData();
  }, [endpoint, params, successCallback, failCallback])
 
  return {
    data,
    loading
  };
}

export default useGetData;

ở trong component nào đó nếu gọi api thì

import useGetData from '@/hooks/useGetData';
...
// trong functional component nào đó
...
const { loading, data } = useGetData('https://api.pornhub.com');

return (<>
{loading ? <LoadingIcon /> : <ListItem items={data}/>}
</>)

có thể tối ưu hơn nữa nhưng đại khái ý tưởng là như vậy :v

với việc chia ra như vầy không chỉ đơn giản việc check loading mà còn có display response/ catch error theo ý muốn. Kiểu như làm 1 cái alert component cho toàn app, fetch data lỗi thì tự hiển thị message mà api trả về... kiểu vậy

P/s: mình viết mã giả thôi nên lỗi cú pháp or import tự fix nhé :v đối số hàm cũng tuỳ chỉnh theo nhu cầu của b

Share
Avatar Nguyen Tuan Anh @TuanAnh9996
Aug 4th, 9:50 AM

ừ nhỉ, mình quên mất vụ hook nay

0
| Reply
Share
Viblo
Let's register a Viblo Account to get more interesting posts.