교육/엘리스 SW 학습 내용
[엘리스sw] 10주차 3일 - Props, State, 이벤트 처리
꼽파
2024. 3. 7. 00:06
◆ Props와 State
◆ 이벤트 처리
Props
props란
- 컴포넌트로 전달되는 매개변수
- 기본적으로 Component에 원하는 값을 넘겨줄 때 사용하며, 넘겨줄 수 있는 값은 변수, 함수, 객체, 배열 등 JavaScript의 요소라면 제한이 없음.
- 주로 component의 '재사용'을 위하여 사용함.
컴포넌트 생성
const Welcome = (props) => {
return <h1>Hello, {props.name}</h1>;
}
컴포넌트 사용
const App = () => {
return <div>
<welcome name="수영" />
<welcome name="민수" />
<welcome name="영희" />
</div>;
}
Props는 읽기 전용이다.
props의 값을 임의 변경해서 사용하면 안 됨.
const Welcome = (props) => {
props.name = props.name + "님";
return <h1>Hello, {props.name}</h1>;
}
props의 값을 변경해서 사용하고 싶으면 새로운 변수를 생성할 것.
const Welcome = (props) => {
const username = props.name + "님";
return <h1>Hello, {username}</h1>;
}
DOM Element의 Attributes
- 기본적인 DOM Element(div, span 등)들의 Attribute는 camel case로 작성한다.
예: tabIndex, className 등 - 그러나 'data-' 또는 'aria-'로 시작하는 Attribute는 예외이다.
예: data-type, aria-label 등 - HTML의 Attribute와 다른 이름을 가지는 Attribute가 있다.
class → className, for → htmlFor 등 - HTML의 Attribute와 다른 동작 방식을 가진 Attribute가 있다.
checked(defaultChecked), value(defaultValue), style 등 - React에서만 쓰이는 새로운 Attribute가 있다.
key, dangerouslySetInnerHTML (string→html) 등
HTML과 다른 방식의 React Attribute(checked, value)
(<input type="checkbox" checked={false} />)
- HTML에서 checked 또는 value는 해당 값이 '초기값'으로 쓰이지만 React 내에서는 현재 값을 의미함.
→ checked 값이 false로 고정돼있는 경우에 사용자가 checkbox를 클릭해도 값의 변화가 일어나지 않음. - 만약 '초기값'의 의미로 checked 또는 value를 사용하고 싶다면 defaultChecked, defaultValue Attribute를 설정하면 됨.
React에서만 쓰이는 새로운 Attribute(key)
- Key는 React가 어떤 항목을 변경, 추가 또는 삭제할지 식별하는 것을 도와줌.
- Key는 element에 안정적인 고유성을 부여하기 위해 배열 내부의 Element에 지정해야 함.
- Key는 배열 안에서 형제 사이에서 고유해야 하고, 전체 범위에서 고유할 필요는 없음.
- 두 개의 다른 배열을 만들 때 동일한 key를 사용할 수 있음.
const Names = () => {
const names = [
{key: '1', value: '민수'},
{key: '2', value: '영희'},
{key: '3', value: '길동'},
]
return (
<div>
{names.map((item) => (
<li key={item.key}>{item.value}</li>
))}
</div>
)
}
State
- State는 Component 내에서 유동적으로 변할 수 있는 값을 저장한다.
- 개발자가 의도한 동작에 의해 변할 수도 있고, 사용자의 입력에 따라 새로운 값으로 변경될 수도 있음.
- State값이 변경되고 재랜더링이 필요한 경우에 React가 자동으로 계산하여 변경된 부분을 렌더링한다.
import { useState } from 'react';
function Example() {
const [count, setCount] = useState(0);
return (
<div>
<p>버튼을 {count}번 눌렀습니다.</p>
<button onClick={() => setCount(count + 1)}>
클릭
</button>
</div>
);
}
State 값을 직접 변경하지 마세요.
- State 값을 직접 변경하게 되면 React가 Component를 다시 렌더링할 타이밍을 알아차리지 못함.
→ 반드시 setState 함수를 이용해 값을 변경해라. - setState 함수를 호출할 때 React에게 "다시 렌더링 해주세요~"라는 명령이 내려진다.
import { useState } from 'react';
function Example() {
let [count, setCount] = useState(0);
return (
<div>
<p>버튼을 {count}번 눌렀습니다.</p>
<button onClick={() => {count = count + 1;}}>
클릭
</button>
</div>
);
}
→ 에러가 나지는 않지만, 화면에서는 증가를 하지 않는다.
State를 변경하는 두 가지 방법
1) setState 내에 변경할 값을 넣기
const [count, setCount] = useState(0);
setCount(count + 1);
2) setState에 함수를 넣기
함수를 넣는 경우 함수가 반환(return)하는 값으로 State가 변경됨.
현재 값을 기반으로 State를 변경하고자 하는 경우 함수를 넣는 방법을 권장함.
const [count, setCount] = useState(0);
setCount((current) => {
return current + 1
});
Object를 갖는 State를 만들 때 주의사항
- user object 안의 grade가 변경되었지만 user 자체가 변경되지 않아서 React가 State의 변경을 감지하지 못함.
const [user, setUser] =
useState({name: "민수", grade: 1})
setUser((current) => {
current.grade = 2;
return current;
})
- 기존 user의 내용을 새로운 object에 담고, grade를 변경한다.
const [user, setUser] =
useState({name: '민수', grade: 1})
setUser((current) => {
const newUser = { ...current }
newUser.grade = 2
return newUser;
})
이벤트 처리
이벤트란?
- 이벤트(event) : 웹 브라우저가 알려주는 HTML 요소에 대한 사건의 발생을 의미함.
- 유저의 행동에 의해 발생할 수도 있으며, 개발자가 의도한 로직에 의해 발생할 수도 있음.
→ 이렇게 발생한 이벤트는 자바스크립트를 이용해 대응할 수 있음.
ex. Element가 로딩되었을 때, 사용자가 Element를 클릭했을 때, 마우스를 올렸을 때, 더블 클릭했을 때, 키보드 입력을 주었을 때 등 다양한 이벤트가 존재함. - 이벤트 핸들러 함수에서는 다양한 로직을 처리하고, 그 결과를 사용자에 출력하여 알릴 수 있음.
이벤트 처리(핸들링) 방법
핸들링 함수 선언
const App = () => {
const handleClick = () => {
alert("클릭했습니다.");
}
return (
<div>
<button onClick={handleClick}>클릭하세요</button>
</div>
);
};
익명 함수로 처리
const App = () => {
return (
<div>
<button onClick={() => {
alert('클릭했습니다.')
}}>클릭하세요</button>
</div>
)
}
이벤트 객체
- DOM Element의 경우 핸들링 함수에 이벤트 object를 매개변수로 전달한다.
- 이벤트 object를 이용하여 이벤트 발생 원인, 이벤트가 일어난 Element에 대한 정보를 얻을 수 있다.
- 이벤트 형태(클릭, 키 입력 등)와 DOM 종류(button, form, input 등)에 따라 전달되는 이벤트 object의 내용이 다르니 유의해야 한다.
const App = () => {
const handleChange = (event) => {
console.log(event.target.value + "라고 입력하셨네요.");
}
return (
<div>
<input onChange={handleChange} />
</div>
);
};
많이 쓰이는 DOM 이벤트
- onClick: Element를 클릭했을 때
- onChange: Element의 내용이 변경되었을 때 (input의 텍스트를 변경, 파일 선택 등)
- onKeyDown, onKeyUp, onKeyPress: 키보드 입력이 일어났을 때
- onDoubleClick: Element를 더블 클릭했을 때
- onFocus: Element에 Focus 되었을 때
- onBlur: Element가 Focus를 잃었을 때
- onSubmit: Form Element에서 Submit 했을 때
컴포넌트 내 이벤트 처리
DOM 버튼 클릭
DOM element의 클릭 이벤트를 전달받아 처리하는 간단한 예제
const App = () => {
const handleClick = () => {
alert("클릭했습니다.");
}
return (
<div>
<button onClick={handleClick}>클릭하세요</button>
</div>
)
}
DOM Input 값을 State에 저장하기
const App = () => {
const [inputValue, setInputValue] = useState("defaultValue");
const handleChange = (event) => {
setInputValue(event.target.value);
}
return (
<div>
<input onChange={handleChange}
defaultValue={inputValue} />
</div>
<br />
입력한 값은: {inputValue}
</div>
);
};
- event object의 target은 이벤트의 원인이 되는 Element를 가리킨다.
- 현재 event의 target은 input element이므로 입력된 value를 가져와 setState를 하는 것이다.
여러 Input 동시에 처리하기
const App = () => {
const [user, setUser] = useState({ name: "민수", school: "엘리스대학교" });
const handleChange = (event) => {
const {name, value} = event.target;
const newUser = { ...user };
newUser[name] = value;
setUser(newUser);
};
return (
<div>
<input name="name" onChange={handleChange}
value={user.name} />
<br />
<input name="school" onChange={handleCahnge} value={user.school} />
<p>
{user.name}님은 {user.school}에 재학중입니다.
</p>
</div>
);
};
- State를 여러 개 선언할 수도 있지만 object를 활용하여 여러 개의 input을 state로 관리하는 방법도 있다.
- target으로부터 name을 받아와 해당 name의 key에 해당하는 value를 변경하여 state에 반영한다.
다른 컴포넌트로 이벤트 전달
컴포넌트간 이벤트 전달하기
- 사용자가 입력한 정보를 현재 컴포넌트가 아닌 부모 컴포넌트에서 활용해야 하는 경우 예시와 같이 이벤트를 Props로 전달하여 처리할 수 있음.
const MyForm = ({ onChange }) => {
return (
<div>
<span>이름: </span>
<input onChange={onChange} />
</div>
)
}
const App = () => {
const [username, setUsername] = useState('')
return (
<div>
<h1>{username}님 환영합니다.</h1>
<MyForm
onChange={(event) => {
setUsername(event.target.value)
}}
/>
</div>
)
}
커스텀 이벤트
const SOS = ({onSOS}) => {
const [count, setCount] = useState(0);
const handleClick = () => {
if (count >= 2) {
onSOS();
}
setCount(count + 1);
}
return <button onClick={handleClick}>
세 번 누르면 긴급호출({count})
</button>
}
const App = () => {
return (
<div>
<SOS
onSOS={() => {
alert("긴급사태!");
}}
/>
</div>
);
};
세 번 연속 눌렀을 때 가능하도록 함.
이벤트 명명법
- 직접 이벤트를 만들 때에는 이름을 자유롭게 설정할 수 있다.
- 그러나 보통은 코드를 읽을 때 쉽고 빠르게 이해할 수 있도록 "on" + 동사 또는 "on" + 명사 + 동사 형태로 작성한다.
- 예시) onClick, onButtonClick, onInputChange 핸들링 함수의 경우
- 마찬가지로 "handle" + 동사 또는 "handle" + 명사 + 동사 의 형태로 작성하며, "handle" 대신 이벤트명과 동일한 "on"을 앞에 붙여도 무방하다.
const App = () => {
const handleClick = () => {
alert("클릭했습니다.);
}
return (
<div>
<button onClick={handleClick}>클릭하세요</button>
</div>
);
};
728x90