fix: 3차 리뷰 LOW — useCallback, 중복 제거, 접근성 강화
Some checks failed
Client CI/CD / test (push) Failing after 34s
Client CI/CD / deploy (push) Has been skipped

- DownloadSection loadInfo useCallback 래핑
- DownloadAdmin reload 중복 → 단일 load 함수
- LoginPage/RegisterPage 에러 메시지 role="alert"

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-15 19:06:15 +09:00
parent e671a1cba6
commit 789dad1e34
4 changed files with 20 additions and 31 deletions

View File

@@ -1,4 +1,4 @@
import { useState, useEffect } from 'react'; import { useState, useEffect, useCallback } from 'react';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { useAuth } from '../context/useAuth'; import { useAuth } from '../context/useAuth';
import { getDownloadInfo } from '../api/download'; import { getDownloadInfo } from '../api/download';
@@ -14,13 +14,13 @@ export default function DownloadSection() {
const { user } = useAuth(); const { user } = useAuth();
const navigate = useNavigate(); const navigate = useNavigate();
const loadInfo = () => { const loadInfo = useCallback(() => {
setReady(false); setReady(false);
setLoadError(false); setLoadError(false);
getDownloadInfo() getDownloadInfo()
.then((data) => { setInfo(data); setReady(true); }) .then((data) => { setInfo(data); setReady(true); })
.catch(() => { setLoadError(true); setReady(true); }); .catch(() => { setLoadError(true); setReady(true); });
}; }, []);
useEffect(() => { loadInfo(); }, []); useEffect(() => { loadInfo(); }, []);

View File

@@ -1,5 +1,5 @@
// TODO: Add tests for CRUD operations (load download info, upload launcher, upload game) // TODO: Add tests for CRUD operations (load download info, upload launcher, upload game)
import { useState, useEffect } from 'react'; import { useState, useEffect, useCallback } from 'react';
import { getDownloadInfo } from '../../api/download'; import { getDownloadInfo } from '../../api/download';
import UploadForm from './UploadForm'; import UploadForm from './UploadForm';
import './AdminCommon.css'; import './AdminCommon.css';
@@ -9,29 +9,7 @@ export default function DownloadAdmin() {
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [loadError, setLoadError] = useState(''); const [loadError, setLoadError] = useState('');
useEffect(() => { const load = useCallback(() => {
getDownloadInfo()
.then((data) => {
setInfo(data);
setLoadError('');
})
.catch((err) => {
console.error('다운로드 정보 로드 실패:', err);
setLoadError('배포 정보를 불러올 수 없습니다.');
})
.finally(() => setLoading(false));
}, []);
if (loading) {
return (
<div className="admin-section">
<h2 className="admin-section-title">게임 배포 관리</h2>
<p className="admin-loading">불러오는 ...</p>
</div>
);
}
const reload = () => {
setLoading(true); setLoading(true);
setLoadError(''); setLoadError('');
getDownloadInfo() getDownloadInfo()
@@ -44,14 +22,25 @@ export default function DownloadAdmin() {
setLoadError('배포 정보를 불러올 수 없습니다.'); setLoadError('배포 정보를 불러올 수 없습니다.');
}) })
.finally(() => setLoading(false)); .finally(() => setLoading(false));
}; }, []);
useEffect(() => { load(); }, [load]);
if (loading) {
return (
<div className="admin-section">
<h2 className="admin-section-title">게임 배포 관리</h2>
<p className="admin-loading">불러오는 ...</p>
</div>
);
}
if (loadError) { if (loadError) {
return ( return (
<div className="admin-section"> <div className="admin-section">
<h2 className="admin-section-title">게임 배포 관리</h2> <h2 className="admin-section-title">게임 배포 관리</h2>
<p className="admin-error">{loadError}</p> <p className="admin-error">{loadError}</p>
<button className="btn-admin-secondary" onClick={reload}>다시 시도</button> <button className="btn-admin-secondary" onClick={load}>다시 시도</button>
</div> </div>
); );
} }

View File

@@ -68,7 +68,7 @@ export default function LoginPage() {
</div> </div>
{justRegistered && <p className="login-success">회원가입이 완료되었습니다. 로그인해주세요.</p>} {justRegistered && <p className="login-success">회원가입이 완료되었습니다. 로그인해주세요.</p>}
{error && <p className="login-error">{error}</p>} {error && <p className="login-error" role="alert">{error}</p>}
<button type="submit" className="btn-login" disabled={loading}> <button type="submit" className="btn-login" disabled={loading}>
{loading ? '로그인 중...' : '로그인'} {loading ? '로그인 중...' : '로그인'}

View File

@@ -118,7 +118,7 @@ export default function RegisterPage() {
/> />
</div> </div>
{error && <p className="login-error">{error}</p>} {error && <p className="login-error" role="alert">{error}</p>}
<button type="submit" className="btn-login" disabled={loading}> <button type="submit" className="btn-login" disabled={loading}>
{loading ? '처리 중...' : '회원가입'} {loading ? '처리 중...' : '회원가입'}