feat(screener): useScreenerMode hook (form|canvas + localStorage)
This commit is contained in:
25
src/pages/stock/screener/hooks/useScreenerMode.js
Normal file
25
src/pages/stock/screener/hooks/useScreenerMode.js
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { useState } from 'react';
|
||||||
|
|
||||||
|
const STORAGE_KEY = 'screener-mode-v1';
|
||||||
|
const VALID_MODES = new Set(['form', 'canvas']);
|
||||||
|
|
||||||
|
function readMode() {
|
||||||
|
try {
|
||||||
|
const v = localStorage.getItem(STORAGE_KEY);
|
||||||
|
return VALID_MODES.has(v) ? v : 'form';
|
||||||
|
} catch {
|
||||||
|
return 'form';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useScreenerMode() {
|
||||||
|
const [mode, setModeState] = useState(readMode);
|
||||||
|
|
||||||
|
const setMode = (m) => {
|
||||||
|
if (!VALID_MODES.has(m)) return;
|
||||||
|
setModeState(m);
|
||||||
|
try { localStorage.setItem(STORAGE_KEY, m); } catch {}
|
||||||
|
};
|
||||||
|
|
||||||
|
return { mode, setMode };
|
||||||
|
}
|
||||||
29
src/pages/stock/screener/hooks/useScreenerMode.test.js
Normal file
29
src/pages/stock/screener/hooks/useScreenerMode.test.js
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import { describe, it, expect } from 'vitest';
|
||||||
|
import { renderHook, act } from '@testing-library/react';
|
||||||
|
import { useScreenerMode } from './useScreenerMode';
|
||||||
|
|
||||||
|
describe('useScreenerMode', () => {
|
||||||
|
it('초기값은 "form"', () => {
|
||||||
|
const { result } = renderHook(() => useScreenerMode());
|
||||||
|
expect(result.current.mode).toBe('form');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('localStorage 에 저장된 값 복원', () => {
|
||||||
|
localStorage.setItem('screener-mode-v1', 'canvas');
|
||||||
|
const { result } = renderHook(() => useScreenerMode());
|
||||||
|
expect(result.current.mode).toBe('canvas');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('손상된 localStorage 는 "form" 으로 fallback', () => {
|
||||||
|
localStorage.setItem('screener-mode-v1', 'INVALID_MODE');
|
||||||
|
const { result } = renderHook(() => useScreenerMode());
|
||||||
|
expect(result.current.mode).toBe('form');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('setMode 호출 시 state 와 localStorage 모두 갱신', () => {
|
||||||
|
const { result } = renderHook(() => useScreenerMode());
|
||||||
|
act(() => result.current.setMode('canvas'));
|
||||||
|
expect(result.current.mode).toBe('canvas');
|
||||||
|
expect(localStorage.getItem('screener-mode-v1')).toBe('canvas');
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user