이번에는 Props와 State에 대해 알아보자.
-기본적으로 컴포넌트에 원하는 값을 넘겨줄 때 사용하며, 넘겨줄 수 있는 값은 변수, 함수, 객체, 배열 등 자바스크립트의 요소라면 제한이 없다.
-주로 컴포넌트의 재사용을 위해 사용한다.
//틀린 예시
const Hello = (props)=>{
props.name = props.name + "님";
return <h1>Hello, {props.name}</h1>
}
//바른 예시
const Hello = (props)=>{
const username = props.name + "님";
return <h1>Hello, {username}</h1>
}
-Props의 값은 임의로 변경해서 사용해선 안되며, 값을 변경하고 싶을 때는 새로운 변수를 생성해서 사용한다.
-기본적인 DOM Element(div, span...) 들의 Attribute는 camel case로 작성한다.
-"data-", "aria-"로 시작하는 Attribute는 예외.
-HTML의 Attribute와 다른 이름을 가지는 Attribute가 있다.
ex) class -> className, for -> htmlFor
-HTML의 Attribute와 다른 동작 방식을 가진 Attribute가 있다.
ex) checked->defaultChecked, value -> defaultValue, style
-리액트에서만 쓰이는 Attribute가 있다.
key, dangerouslySetInnerHTML
-HTML에서 checked나 value는 해당 값이 초기값으로 쓰이지만 리액트에서는 현재값을 의미한다. 이 말은 checked값이 false로 고정되어 있는 경우 사용자가 checkbox를 클릭해도 값으 변화가 없다.
-만약 초기값의 의미로 checked 또는 value를 사용하려면 defaultChecked, defaultValue Attribute를 설정한다.
-Key는 리액트가 어떤 항목을 변경, 추가, 삭제할지 식별하는 것을 돕는다.
-Key는 엘리먼트에 안정적인 고유성을 부여하기 위해 배열 내부의 Element에 지정해야한다.
-Key는 배열 안에서 형제 사이에서 고유해야 하고 전체 범위에서 고유할 필요는 없다.
-두 개의 다른 배열을 만들 때 동일한 Key를 사용할 수 있다.
-State는 컴포넌트 내에서 유동적으로 변할 수 있는 값을 저장한다.
-개발자가 의도한 동작에 의해 변하거나 사용자의 입력에 따라 새로운 값으로 변경될 수 있다.
-State 값이 변경되고 재렌더링이 필요한 경우 리액트가 자동으로 계산 해 변경된 부분을 렌더링한다.
-State값을 직접 변경하게 되면 리액트가 컴포넌트를 다시 렌더링 할 타이밍을 알아채지 못한다.
-반드시 setState 값을 이용해 변경해야한다.
-setState 함수를 호출할 때 리액트에게 재렌더링 명령이 내려진다.
//setState에 변경할 값 넣기
const [count, setCount] = useState(0);
setCount(count + 1);
//setState에 함수 넣기
const [count, setCount] = useState(0);
setCount((current)) => {
return current + 1
})
-setState함수에는 변경할 값을 직접 넣는 방법, 함수를 넣는 방법이 있다.
함수를 넣는 경우 함수가 return 하는 값으로 State가 변경된다.
현재 값을 기반으로 State를 변경하고자 하는 경우 함수를 넣는 방법이 권장된다.
-이벤트(event)란 웹 브라우저가 알려주는 HTML 요소에 대한 사건의 발생을 의미하며, 유저의 행동 혹은 개발자가 의도한 로직에 의해 발생한다.
-Element가 로딩되었을 때, 사용자가 Element를 클릭했을 때, 마우스를 올렸을 때, 더블클릭 했을 때, 키보드 입력을 주었을 때 등 다양한 이벤트가 존재한다.
-이벤트 핸들러 함수에서는 다양한 로직을 처리하고 그 결과를 사용자에게 출력하여 알릴 수 있다.
//핸들링 함수 선언
function App() {
const handleClick = () => {
alert("클릭했음");
}
return (
<>
<button onClick={handleClick}>클릭</button>
</>
);
};
//익명 함수로 처리
function App() {
return (
<>
<button onClick={()=>{
alert("클릭했음")
}}>클릭</button>
</>
);
};
-리액트에서 이벤트를 처리하는 방법은 두가지가 있는데, 별도의 핸들링 함수를 선언하고 Element에 넘겨주는 방법과 이벤트를 할당하는 부분에 익명 함수를 작성하는 방법이 있다.
-DOM Element의 경우 핸들링 함수에 이벤트 객체를 매개변수로 전달한다.
-이벤트 객체를 이용해 이벤트 발생 원인, 이벤트가 일어난 Element에 대한 정보를 얻을 수 있다.
-이벤트 형태(클릭, 키 입력 등)와 DOM 종류(button, form, input 등)에 따라 전달되는 이벤트 객체의 내용도 다르다.
-onClick: Element를 클릭했을 때
-onChange: Element의 내용이 변경되었을 때
-onKeyDown, onKeyUp, onKeyPress: 키보드 입력이 일어났을 때
-onDoubleClick: Element를 더블 클릭 했을 때
-onFocus: Element에 Focus 되었을 때
-onBlur: Element가 Focus를 잃었을 때
-onSubmit: Form Element에서 Submit 했을 때
function App() {
const handleClick = () => {
alert("클릭했음");
}
return (
<>
<button onClick={handleClick}>클릭</button>
</>
);
};
-DOM 버튼 클릭
function App() {
const [inputValue, setInputValue] = useState("defaultValue");
const handleChange = (event) => {
setInputValue(event.target.value)
}
return (
<>
<input onChange={handleChange} defaultValue={inputValue} />
<h1>입력 값: {inputValue}</h1>
</>
);
};
-DOM Input값 State에 저장
event object의 target은 이벤트의 원인이 되는 Element를 가리킨다.
function App() {
const [user, setUser] = useState({
name: "창현",
schoo: "서울대학교"
});
const handleChange = (event) => {
const { name, value } = event.target;
const newUser = { ...user };
newUser[name] = value;
setUser(newUser);
};
return (
<>
<input name="name" onChange={handleChange} value={user.name} />
<input name="school" onChange={handleChange} value={user.school} />
<h1>{user.name}님은 {user.school}에 재학중입니다.</h1>
</>
);
-여러 Input 동시에 처리하기
target으로부터 name을 받아와 해당 name의 key에 해당하는 value를 변경하여 state에 반영한다.
-직접 이벤트를 만들 때는 이름은 자유롭게 설정할 수 있으나 코드를 읽을 때 쉽고 빠르게 이해할 수 있도록 on + 동사 또는 on + 명사 + 동사 형태로 작성한다.
ex) onClick, onButtonClick
-핸들링 함수의 경우 마찬가지로 handle + 동사 또는 handle + 명사 + 동사의 형태로 작성한다.