Contentext 설정하기
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;
};
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')
);
Header
에서 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;
hasNoti
상태를 전역적으로 관리할 수 있습니다.NotificationContext
를 만들어 상태를 저장하고, useNotification
훅을 통해 컴포넌트에서 상태를 가져와 사용할 수 있습니다.NotificationProvider
로 애플리케이션을 감싸야 hasNoti
값을 전역에서 공유할 수 있습니다.