const [userAnswers, setUserAnswers] = useState([]);
const activeQuestionIndex = userAnswers.length;
const quizIsComplete = activeQuestionIndex === QUESTIONS.length;
const handleSelectAnswer = useCallback((selectAnswer) => {
setUserAnswers((prev) => {
return [...prev, selectAnswer];
});
}, []);
const handleSkipAnswer = useCallback(
() => handleSelectAnswer(null),
[handleSelectAnswer]
);
....
<QuestionTimer
key={activeQuestionIndex}
timeout={10000}
onTimeout={handleSkipAnswer}
/>
<ul id="answers">
{suffleAnswer.map((answer) => (
<li key={answer} className="answer">
<button onClick={() => handleSelectAnswer(answer)}>
{answer}
</button>
</li>
))}
useCallback
⇒ useCallback을 사용하는 이유: 성능 최적화를 위해(렌더링될 때마다 새로 생성 방지)
- handleSelectAnswer 사용자가 선택한 답변을 userAnswers 상태에 추가하는 함수. useCallback을 사용하면 컴포넌트가 다시 렌더링 될 때마다 새로운 함수가 생성되는 것을 방지함.
- handleSkipAnswer 사용자가 답변을 선택할 때는 button의 handleSelectAnswer(answer) 가 실행됨으로써 userAnswers 배열에 주차된다. ****handleSelectAnswer(null) : 사용자가 답변을 선택하지 않았을 때(타임아웃 발생) null값을 userAnswers 배열에 추가.
메모이제이션
= 이전에 계산한 값을 캐싱해두고 같은 입력이 들어왔을 때 다시 계산하지 않고 캐시에 저장된 값을 바로 전환하는 최적화 기법.
- useCallback : 함수 메모이제이션을 위한 것
- useMemo: 값(변수) 메모이제이션을 위한 것
key
= key를 userAnswers 배열의 길이가 변경될 때마다 QuestionTimer 컴포넌트의 key값이 변하게 되서 문제마다 타이머가 로딩 됨.
- key는 어느 요소나 컴포넌트에 들어갈 수 있고 고유하게 식별하기 위해 사용
- 리액트가 찾을 수 있는 빌트인 속성
- 컴포넌트가 변경될 때면 오래 된 인스턴스를 삭제하고 재생성함.
'언어 > React.js' 카테고리의 다른 글
[cors 오류] 알라딘 api cors 연결하기 (0) | 2025.01.11 |
---|---|
[React] typescript zustand 이용하기 (1) | 2024.12.19 |
Side Effects 다루기 (0) | 2024.10.18 |
[React] 내가 보려고 쓴 리액트 (0) | 2023.10.26 |
[React] useEffect() (0) | 2023.10.24 |