728x90
1.1 Context 설정하기
import React, { createContext, useState, useContext, ReactNode } from 'react';
// NotificationContext 생성
interface NotificationContextType {
hasNoti: boolean;
setHasNoti: (value: boolean) => void;
}
const NotificationContext = createContext<NotificationContextType | undefined>(undefined);
interface NotificationProviderProps {
children: ReactNode; // children 타입을 명시적으로 정의
}
// NotificationProvider 컴포넌트
export const NotificationProvider: React.FC<NotificationProviderProps> = ({ children }) => {
const [hasNoti, setHasNoti] = useState<boolean>(false);
return (
<NotificationContext.Provider value={{ hasNoti, setHasNoti }}>
{children}
</NotificationContext.Provider>
);
};
// Context를 사용하는 훅
export const useNotification = () => {
const context = useContext(NotificationContext);
if (!context) {
throw new Error('useNotification must be used within a NotificationProvider');
}
return context;
};
1.2 NotificationProvider로 전체 앱을 감싸기
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { NotificationProvider } from './context/NotificationContext'; // 방금 만든 파일 경로
ReactDOM.render(
<React.StrictMode>
<NotificationProvider>
<App />
</NotificationProvider>
</React.StrictMode>,
document.getElementById('root')
);
1.3 Header에서 hasNoti 사용하기
이제 Header 컴포넌트에서 useNotification 훅을 사용하여 hasNoti 값을 접근하고 수정할 수 있습니다.
import React, { useState, useEffect, useRef } from 'react';
import { Link } from 'react-router-dom';
import './Header.css';
import mainCharacterImg from '../img/main_character.png';
import UserProfile from './UserProfile';
import no_notification from '../img/no_notification.png';
import has_notification from '../img/has_notification.png';
import Notification from '../main/Notification';
import { useNotification } from '../context/NotificationContext';
interface ProfileProps {
pageType: 'profileSetting' | 'signup' | 'logout' | 'otherblog' | 'myBlog';
}
const Header: React.FC<ProfileProps> = ({ pageType }) => {
const notificationButtonRef = useRef<HTMLDivElement>(null); // 알림 버튼 참조
const { hasNoti, setHasNoti } = useNotification(); // 전역 상태 사용
const [nickname, setNickname] = useState<string>();
const [message, setMessage] = useState<string>('');
const [image, setImage] = useState<string>(mainCharacterImg);
const [isImageLoaded, setIsImageLoaded] = useState<boolean>(false);
const [token, setToken] = useState<string>('');
const [openNotification, setOpenNotification] = useState<boolean>(false);
const closeModal = () => {
setOpenNotification(false);
// 알림을 다 확인한 경우에만 false로 변경
if (/* 조건 */) {
setHasNoti(false);
}
};
useEffect(() => {
// 세션스토리지에서 닉네임과 토큰 가져오기
try {
const localStorageToken = sessionStorage.getItem('accessToken');
if (localStorageToken === null) {
setToken('');
} else {
setToken(localStorageToken);
}
const storedNickname = sessionStorage.getItem('nickname');
if (storedNickname) {
setNickname(storedNickname);
setMessage(sessionStorage.getItem('message'));
setImage(sessionStorage.getItem('image') || mainCharacterImg);
}
} catch (err) {
console.log(err);
}
}, []);
const profileImage = isImageLoaded ? image : mainCharacterImg;
return (
<header className="header">
{/* Header 구조 */}
<div className="header__auth">
<div ref={notificationButtonRef} onClick={() => setOpenNotification(true)}>
{openNotification && notificationButtonRef.current && (
<Notification onClose={closeModal} buttonRef={notificationButtonRef} />
)}
{hasNoti ? (
<img src={has_notification} style={{ width: '20px', height: 'auto', marginRight: '20px' }} />
) : (
<img src={no_notification} style={{ width: '20px', height: 'auto', marginRight: '20px' }} />
)}
</div>
{profileImage && <UserProfile profileType={'logout'} profileImage={profileImage}></UserProfile>}
</div>
</header>
);
};
export default Header;
요약:
- Context API를 통해 hasNoti 상태를 전역적으로 관리할 수 있습니다.
- NotificationContext를 만들어 상태를 저장하고, useNotification 훅을 통해 컴포넌트에서 상태를 가져와 사용할 수 있습니다.
- NotificationProvider로 애플리케이션을 감싸야 hasNoti 값을 전역에서 공유할 수 있습니다.
728x90
'웹개발' 카테고리의 다른 글
[React] useTranslation 을 통해 다국어 지원하기 (feat.i18next) (0) | 2024.10.14 |
---|---|
[css] position 속성 (0) | 2024.09.27 |
[React] 'react-beautiful-dnd' 를 사용하여, 드래그 엔 드롭 구현하기 (drag and drop) (0) | 2024.09.05 |
[React] ReactQuill 을 사용하여 이미지를 서버에 보낼 때 src 길이 줄이기 및 실제 이미지에는 영향 안끼치는 방법 (0) | 2024.09.05 |
[React] IntersectionObserver DOM의 업데이트(예: 좋아요 버튼 클릭) 이후에야 비로소 IntersectionObserver가 다시 작동할때 (3) | 2024.08.28 |