💡 참고 : 선언형 UI와 명령형 UI의 차이점?
명령형 UI : 세밀하게 직접 조작해야 하는 UI
선언형 UI : 시각적 state로 묘사된 UI
리액트처럼 생각하는 방법은 UI를 선언적인 방식으로 생각하는 것이다.
UI
를 선언적인 방식으로 생각하는 5단계사용자가 볼 수 있는 UI의 모든 "state"를 확인한다.
state
변화를 트리거하는지 알아내기두 종류의 인풋 유형으로 state 변경을 트리거할 수 있다.
Human inputs : 버튼을 누르거나, 필드를 입력하거나, 링크를 이동하는 것
Computer inputs : 네트워크 응답이 오거나, 타임아웃이 되거나, 이미지를 로딩하는 것
두 가지 모두 UI를 업데이트하기 위해서는 state 변수를 설정해야 한다.
state
를 useState
로 표현하기각각의 state는 "움직이는 조각"이다.
여기서 주의할 점은 "state (움직이는 조각)"는 적을수록 좋다는 것이다.
state가 많아 복잡해지면 버그를 일으킬 위험이 높아지기 때문이다!
state
변수 제거하기state가 역설을 일으키지는 않는지? 다른 state 변수에 이미 같은 정보가 담겨있진 않는지? 등 정리 과정을 거친 후,
필수적으로 필요한 state 변수만을 남겨둔다.
state
설정을 위해 이벤트 핸들러 연결하기다음 예시 코드처럼 state 변수 설정을 위해 이벤트 핸들러를 연결해준다.
import { useState } from 'react';
const Form = () => {
const [answer, setAnswer] = useState('');
const [error, setError] = useState(null);
const [status, setStatus] = useState('typing');
if (status === 'success') {
return <h1>That's right!</h1>
}
const handleSubmit = (e) => {
e.preventDefault();
setStatus('submitting');
try {
await submitForm(answer);
setStatus('success');
} catch (error) {
setStatus('typing');
setError(error);
}
}
return (
<>
<h2>Quiz</h2>
<p>Can you Guess What Number that i'm thinking on my head?</p>
<form onSubmit={handleSubmit}> // ⬅️ 이벤트 핸들러 연결
<textarea
value={answer}
onChange={(e) => setAnswer(e.target.value)}
disabled={status === 'submitting'}
/>
<br />
<button
disabled={ answer.length === 0 || status === 'submitting' }
>Submit</button>
{error !== null && <p>{error.message}</p>}
</form>
</>
)
}
const submitForm = (answer) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
let shouldError = answer.toLowerCase() !== 'lima';
if(shouldError) {
reject(new Error('Good guess but a wrong answer.'));
} else {
resolve();
}
}, 1500);
});
}