๐Ÿ“ก 52. React Native ๋„คํŠธ์›Œํฌ ์ƒํƒœ ๊ฐ์ง€์™€ ์˜คํ”„๋ผ์ธ ๋Œ€์‘ ์ „๋žต โ€” NetInfo๋กœ UX ์ฑ™๊ธฐ๊ธฐ

JM_Devยท2025๋…„ 6์›” 17์ผ
0
post-thumbnail

๋ชจ๋ฐ”์ผ ์•ฑ์€ ์–ธ์ œ๋‚˜ ์ธํ„ฐ๋„ท์ด ๋˜๋Š” ํ™˜๊ฒฝ์—์„œ๋งŒ ์‹คํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค.
์ง€ํ•˜์ฒ , ์—˜๋ฆฌ๋ฒ ์ดํ„ฐ, ํ•ด์™ธ ๋„คํŠธ์›Œํฌ ํ™˜๊ฒฝ ๋“ฑ์—์„œ
๋„คํŠธ์›Œํฌ๊ฐ€ ๋Š๊ธฐ๊ฑฐ๋‚˜ ๋ถˆ์•ˆ์ •ํ•œ ๊ฒฝ์šฐ๊ฐ€ ์ž์ฃผ ๋ฐœ์ƒํ•œ๋‹ค.

๊ทธ๋ž˜์„œ ์•ฑ์€ ์˜คํ”„๋ผ์ธ ์ƒํƒœ์—์„œ๋„ ์ตœ์†Œํ•œ์˜ UX๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค.

์ด๋ฒˆ ๊ธ€์€ React Native์—์„œ ๋„คํŠธ์›Œํฌ ์—ฐ๊ฒฐ ์ƒํƒœ๋ฅผ ๊ฐ์ง€ํ•˜๊ณ  ๋Œ€์‘ํ•˜๋Š” ์ „๋žต์„ ์ •๋ฆฌํ•œ ๊ธ€์ด๋‹ค.


โœ… NetInfo ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค์น˜

npm install @react-native-community/netinfo
  • Android, iOS ๋ชจ๋‘ ์ง€์›
  • ์‹ค์‹œ๊ฐ„ ์—ฐ๊ฒฐ ์ƒํƒœ ๊ฐ์ง€ ๊ฐ€๋Šฅ
  • ์—ฐ๊ฒฐ ์œ ํ˜• (Wi-Fi, Cellular ๋“ฑ) ๋„ ํ™•์ธ ๊ฐ€๋Šฅ

๐Ÿ”ง ๋„คํŠธ์›Œํฌ ์ƒํƒœ ๊ฐ์ง€ ์ฝ”๋“œ ์˜ˆ์‹œ

import NetInfo from '@react-native-community/netinfo';

useEffect(() => {
  const unsubscribe = NetInfo.addEventListener((state) => {
    console.log('isConnected:', state.isConnected);
    console.log('connectionType:', state.type);
  });

  return () => {
    unsubscribe();
  };
}, []);

๐Ÿ“ก ์ƒํƒœ ๊ฐ’ ๊ตฌ์กฐ

{
  isConnected: true,
  isInternetReachable: true,
  type: 'wifi', // or 'cellular', 'none', ...
}
  • isConnected: ๋„คํŠธ์›Œํฌ ์—ฐ๊ฒฐ ์—ฌ๋ถ€
  • isInternetReachable: ์ธํ„ฐ๋„ท ์‹ค์ œ ๋„๋‹ฌ ๊ฐ€๋Šฅ ์—ฌ๋ถ€
  • type: ์—ฐ๊ฒฐ ๋ฐฉ์‹ (wifi, cellular, none ๋“ฑ)

๐Ÿ’ก ์˜คํ”„๋ผ์ธ ์ƒํƒœ ํ‘œ์‹œ ์˜ˆ์‹œ

const [isOffline, setIsOffline] = useState(false);

useEffect(() => {
  const unsubscribe = NetInfo.addEventListener((state) => {
    setIsOffline(!state.isConnected || !state.isInternetReachable);
  });

  return () => unsubscribe();
}, []);

{isOffline && (
  <View style={{ backgroundColor: 'red', padding: 8 }}>
    <Text style={{ color: 'white' }}>๐Ÿ“ด ๋„คํŠธ์›Œํฌ ์—ฐ๊ฒฐ์ด ๋Š๊ฒผ์Šต๋‹ˆ๋‹ค</Text>
  </View>
)}

โœ… ์ƒํƒœ ๋ฐ”์ฒ˜๋Ÿผ ์ƒ๋‹จ์— ๋„์šฐ๊ธฐ
โœ… Navigation ๋ฐ–์— Global Banner๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ๋„ ํ•จ


๐Ÿ” ๋„คํŠธ์›Œํฌ ์žฌ์‹œ๋„ ์ „๋žต

์ƒํ™ฉ์ฒ˜๋ฆฌ ๋ฐฉ๋ฒ•
API ์š”์ฒญ ์‹œ ์‹คํŒจ์ƒํƒœ ์ €์žฅ ํ›„ ์žฌ์‹œ๋„ ๋ฒ„ํŠผ ์ œ๊ณต
์•ฑ ์ง„์ž… ์‹œ ๋„คํŠธ์›Œํฌ ์—†์Œ์•ˆ๋‚ด ๋ฉ”์‹œ์ง€ + pull to refresh UI
์ž๋™ ์žฌ์š”์ฒญ ํ•„์š”SWR, React Query์˜ retry ์„ค์ • ํ™œ์šฉ

๐Ÿง  ์‹ค์ „ ํŒ

  • ์•ฑ ๋กœ๋”ฉ ์‹œ์ ๋ถ€ํ„ฐ NetInfo.fetch()๋กœ ์ดˆ๊ธฐ ์ƒํƒœ ํ™•์ธ
  • isConnected === true ์—ฌ๋„ isInternetReachable === false์ผ ์ˆ˜ ์žˆ์Œ (wifi ์—ฐ๊ฒฐ but no ์ธํ„ฐ๋„ท)
  • ์˜คํ”„๋ผ์ธ ์ƒํƒœ๋ฅผ Zustand๋กœ ์ „์—ญ ๊ด€๋ฆฌํ•˜์—ฌ ์‚ฌ์šฉ์„ฑ ํ–ฅ์ƒ
  • ๋„คํŠธ์›Œํฌ ๋ณ€ํ™” ์ด๋ฒคํŠธ๋Š” ๋„ˆ๋ฌด ์žฆ์œผ๋‹ˆ debounce ์ฒ˜๋ฆฌ ๊ถŒ์žฅ

๐Ÿ“ ๋‚ด๊ฐ€ ๋А๋‚€ ์ 

์˜ˆ์ „์—” "์ธํ„ฐ๋„ท ์—†์œผ๋ฉด ๊ทธ๋ƒฅ ์•ˆ ๋˜์ง€ ๋ญ" ํ•˜๊ณ  ๋ฌด์‹œํ–ˆ๋Š”๋ฐ,
์œ ์ € ์ž…์žฅ์—์„  ์•ฑ์ด ๋ป—์€ ๊ฑธ๋กœ ๋ณด์ด๊ณ , ๋ถˆํŽธํ•˜๋‹ค๋Š” ํ”ผ๋“œ๋ฐฑ์ด ๋งŽ์•˜๋‹ค.

์ง€๊ธˆ์€ ์•ฑ ์ „์—ญ์—์„œ ๋„คํŠธ์›Œํฌ ์ƒํƒœ๋ฅผ ๊ฐ์ง€ํ•ด์„œ
์˜คํ”„๋ผ์ธ ๋ฐฐ๋„ˆ, ๋ฐ์ดํ„ฐ ์žฌ์‹œ๋„, ์บ์‹œ ๋ฐ์ดํ„ฐ ์ œ๊ณต ๋“ฑ์œผ๋กœ UX๋ฅผ ์ตœ๋Œ€ํ•œ ์œ ์ง€ํ•˜๊ณ  ์žˆ๋‹ค.


๐Ÿ“ถ โ€œ์ข‹์€ ์•ฑ์€ ์—ฐ๊ฒฐ์ด ๋Š๊ฒจ๋„ ์œ ์ €๋ฅผ ๋†“์ง€ ์•Š๋Š”๋‹ค.โ€


profile
๊ฐœ๋ฐœ์ž๋กœ ์ทจ์—…์„ ์ค€๋น„ ์ค‘ ์ด๋ฉฐ, ์—ด์‹ฌํžˆ ๊ณต๋ถ€ ์ค‘ ์ž…๋‹ˆ๋‹ค!

0๊ฐœ์˜ ๋Œ“๊ธ€