React State & Props
예를 들어 HTML에서 이벤트 처리 방식이 아래와 같다면,
<button onclick="handleEvent()">Event</button>
React의 이벤트 처리 방식은 아래와 같습니다.
<button onClick={handleEvent}>Event</button>
onChange
<input>
<textarea>
<select>
와 같은 폼(Form) 엘리먼트는 사용자의 입력값을 제어하는 데 사용됩니다.
React
에서는 이러한 변경될 수 있는 입력값을 일반적으로 컴포넌트의 state
로 관리하고 업데이트합니다.
onChange
이벤트가 발생하면 e.target.value
를 통해 이벤트 객체에 담겨있는 input
값을 읽어올 수 있습니다.
컴포넌트 return
문 안의 input
태그에 value
와 onChange
를 넣어주었습니다.
onChange는
input`의 텍스트가 바뀔 때마다 발생하는 이벤트입니다.
이벤트가 발생하면 handleChange
함수가 작동하며, 이벤트 객체에 담긴 input
값을 setState
를 통해 새로운 state
로 변경합니다.
function NameForm() {
const [name, setName] = useState("");
const handleChange = (e) => {
setName(e.target.value);
}
return (
<div>
<input type="text" value={name} onChange={handleChange}></input>
<h1>{name}</h1>
</div>
)
};
onClick
nClick
이벤트는 말 그대로 사용자가 클릭이라는 행동을 하였을 때 발생하는 이벤트입니다.
버튼이나 <a>
tag를 통한 링크 이동 등과 같이 주로 사용자의 행동에 따라 애플리케이션이 반응해야 할 때 자주 사용하는 이벤트입니다.
그럼 위의 onChange
예시에 버튼을 추가하여 버튼 클릭 시 input tag에 입력한 이름이 alert
을 통해 알림 창이 팝업 되도록 코드를 추가해 보겠습니다.
function NameForm() {
const [name, setName] = useState("");
const handleChange = (e) => {
setName(e.target.value);
}
return (
<div>
<input type="text" value={name} onChange={handleChange}></input>
<button onClick={alert(name)}>Button</button>
<h1>{name}</h1>
</div>
);
};
위와 같이 onClick 이벤트에 alert(name) 함수를 바로 호출하면 컴포넌트가 렌더링 될 때 함수 자체가 아닌 함수 호출의 결과가 onClick에 적용됩니다.
때문에 버튼을 클릭할 때가 아닌, 컴포넌트가 렌더링 될 때에 alert이 실행되고 따라서 그 결과인 undefined(함수는 리턴 값이 없을 때 undefined를 반환합니다.)가 onClick에 적용되어 클릭했을 때 아무런 결과도 일어나지 않습니다.
따라서 onClick 이벤트에 함수를 전달할 때는 함수를 호출하는 것이 아니라 아래와 같이 리턴문 안에서 함수를 정의하거나 리턴문 외부에서 함수를 정의 후 이벤트에 함수 자체를 전달해야 합니다.
// 함수 정의하기
return (
<div>
...
<button onClick={() => alert(name)}>Button</button>
...
</div>
);
};
// 함수 자체를 전달하기
const handleClick = () => {
alert(name);
};
return (
<div>
...
<button onClick={handleClick}>Button</button>
...
</div>
);
};
Controlled Component
React
데이터 흐름모든 데이터를 상태로 둘 필요는 없습니다. 사실 상태는 최소화하는 것이 가장 좋습니다.
상태가 많아질수록 애플리케이션은 복잡해집니다.
어떤 데이터를 상태로 두어야 하는지는 다음 세 가지 질문을 통해 판단해 보세요.
- 부모로부터 props를 통해 전달됩니까?
- 그러면 확실히 state가 아닙니다.
- 시간이 지나도 변하지 않나요?
- 그러면 확실히 state가 아닙니다.
- 컴포넌트 안의 다른 state나 props를 가지고 계산 가능한가요?
- 그렇다면 state가 아닙니다.