Loading indicator có lẽ là component huyền thoại mà dự án nào cũng cần đến. Hôm nay mình sẽ hướng dẫn các bạn viết nó thành dạng global component để có thẻ được gọi tại bất kỳ đâu trong ứng dụng của bạn. Chúng ta cùng bắt đầu nhé.
Để hiểu thêm về React Context API & Hooks các bạn tham khảo thêm tại đây:
Chúng ta bắt đầu bằng việc tạo một dự án mới sử dụng React nhé. Trong bài viết này mình sẽ sử dụng create-react-app cùng với yarn để tạo project mới. Các bạn xem hướng dẫn cài yarn tại đây nhé.
Tạo một project mới
- Cài
create-react-apppackage:
hieunv@HieuNV ~ % yarn global add create-react-app
yarn global v1.22.0
[1/4] ? Resolving packages...
[2/4] ? Fetching packages...
[3/4] ? Linking dependencies...
[4/4] ? Building fresh packages...
success Installed "create-react-app@3.4.0" with binaries:
- create-react-app
✨ Done in 14.08s.
- Sau khi cài xong thì các bạn tạo project mới như sau:
yarn create react-app loading

Tạo React context mới để lưu trạng thái của Loading component
context/loading.js
import React, { useContext } from 'react';
export const LoadingContext = React.createContext();
export const useLoading = () => useContext(LoadingContext);
Tạo LoadingProvider để lưu trạng thái loading như là một global state.
providers/LoadingProvider.jsx
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import { LoadingContext } from '../../contexts/loading';
export function LoadingProvider(props) {
const [loading, setLoading] = useState(false);
return (
<LoadingContext.Provider
value={{
loading: loading,
show: () => setLoading(true),
hide: () => setLoading(false)
}}>
{props.children}
</LoadingContext.Provider>
);
}
LoadingProvider.propTypes = {
children: PropTypes.node
};
Như các bạn nhìn thấy trong đoạn mã trên chúng ta đã sử dụng LoadingContext truyền trang thái loading và các hàm show và hide xuống các component con thông qua React Context.
Tại App component bạn đặt LoadingProvider là component cao nhất để tất các các component con bên trong có thể gọi các hàm show và hide khi cần thiết.
App.js
import React from 'react';
import { LoadingProvider } from './providers/LoadingProvider';
import { useLoading } from './context/loading.js';
import logo from './logo.svg';
import './App.css';
function App() {
const { show, hide } = useLoading();
return (
<LoadingProvider>
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a className="App-link" href="https://reactjs.org" target="_blank" rel="noopener noreferrer">
Learn React
</a>
</header>
</div>
</LoadingProvider>
);
}
export default App;
Tại component bạn muốn gọi show hay hide loading thì chỉ cần thực hiện như sau:
- import hàm
useLoading()được khai báo trongcontext/loading.js
import { useLoading } from './context/loading.js';
- Trong component bạn sử dụng hook
useLoadingđể lấy các hàmshowvàhide:
const { show, hide } = useLoading();
Giờ chúng ta sửa lại một chút ở LoadingProvider để có thể show loading indicator
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import { LoadingContext } from '../../contexts/loading';
function Loading() {
return <div>Loading...</div>;
}
export function LoadingProvider(props) {
const [loading, setLoading] = useState(false);
return (
<LoadingContext.Provider
value={{
loading: loading,
show: () => setLoading(true),
hide: () => setLoading(false)
}}>
<>
{loading && <Loading />}
{props.children}
</>
</LoadingContext.Provider>
);
}
LoadingProvider.propTypes = {
children: PropTypes.node
};
Các bạn để ý component Loading nhé. Chúng ta chỉ cần thêm một chút kỹ thuật css để cho component này đề lên trên tất cả các component khác bằng z-index đã có được loading indicator có thể được gọi ở bất kỳ đâu rồi.
Cám ơn các bạn đã theo dõi bài viết. Hy vọng bài viết có thể giúp ích cho dự án của các bạn.

Leave a Reply to Code of destiny Cancel reply