오늘은 React의 state와 props에 대해...
state : 컴포넌트 사용 중 컴포넌트 내부에서 변할 수 있는 값
props : 외부로부터 전달받은 값
function Parent() {
return (
<div className="parent">
<h1>I'm the parent</h1>
<Child text={"I'm the eldest child"} />
</div>
);
}
function Child(props) { return (
<div className="child">
<p>{props.text}</p>
</div>
);
}
props를 전달하는 또 다른 방법으로 여는 태그와 닫는 태그의 사이에 value를 넣어 전달할 수 있음.
이 경우 props.children
을 이용하면 해당 value에 접근하여 사용할 수 있음.
function Parent() {
return (
<div className="parent">
<h1>I'm the parent</h1>
<Child>I'm the eldest child</Child>
</div>);
};
function Child(props) {
return (
<div className="child">
<p>{props.children}</p>
</div>);
};
컴포넌트 내에서 변할 수 있는 값, 즉 상태는 React state로 다뤄야 한다.
React에서는 state를 다루는 방법 중 하나로 useState라는 특별한 함수를 제공함.
import { useState } from "react";
function CheckboxExample() {
const [isChecked, setIsChecked] = useState(false);
/*
const stateHookArray = useState(false);
const isChecked = stateHookArray[0];
const setIsChecked = stateHookArray[1];
*/
}
const [state 저장 변수, state 갱신 함수] = useState(상태 초기 값);
<span>{isChecked ? "Checked!!" : "Unchecked"}</span>
function CheckboxExample() {
const [isChecked, setIsChecked] = useState(false);
const handleChecked = (event) => {
setIsChecked(event.target.checked);
};
return (
<div className="App">
<input type="checkbox" checked={isChecked} onChange={handleChecked} />
<span>{isChecked ? "Checked!!" : "Unchecked"}</span>
</div>);
}
React의 이벤트 처리(이벤트 핸들링 Event handling) 방식은 DOM의 이벤트 처리 방식과 유사하지만 몇 가지 문법 차이가 있음
// HTML
<button onclick="handleEvent()">Event</button>
// React
<button onClick={handleEvent}>Event</button>
자주 사용되는 이벤트 처리 예시
input, textarea, select와 같은 Form 엘리먼트는 사용자의 입력값을 제어하는데 사용됨. React에서는 이러한 변경될 수 있는 입력값을 일반적으로 컴포넌트의 state로 관리하고 업데이트함. onChange이벤트가 발생하면 e.target.value를 통해 이벤트 객체에 담겨있는 input 값을 읽어올 수 있음.
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>)
};
사용자가 클릭이라는 행동을 했을 때 발생하는 이벤트. 버튼이나 a tag를 통한 링크 이동 등과 같이 주로 사용자의 행동에 따라 애플리케이션이 반응해야 할 때 자주 사용하는 이벤트.
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 이벤트에 함수를 전달할 때는 함수를 호출하는 것이 아니라 리턴문 안에서 함수를 정의하거나 리턴문 외부에서 함수를 정의 후 이벤트에 함수 자체를 전달해야함.
단, 두 가지 방법 모두 arrow function을 사용하여 함수를 정의하여야 해당 컴포넌트가 가진 state에 함수들이 접근할 수 있음.
import React, { useState } from "react";
import "./styles.css";
function SelectExample() {
const [choice, setChoice] = useState("apple");
const fruits = ["apple", "orange", "pineapple", "strawberry", "grape"];
const options = fruits.map((fruit) => {
return <option value={fruit}>{fruit}</option>;
});
console.log(choice);
const handleFruit = (event) => {
setChoice(event.target.value);
};
return (
<div className="App">
<select onChange={handleFruit}>{options}</select>
<h3>You choose "{choice}"</h3>
</div>
);
}
export default SelectExample;
import React, { useState } from "react";
import "./styles.css";
function App() {
const [showPopup, setShowPopup] = useState(false);
const togglePopup = () => {
setShowPopup(!showPopup);
};
return (
<div className="App">
<h1>Fix me to open Pop Up</h1>
<button className="open" onClick={togglePopup}>Open me</button>
{showPopup ? (
<div className="popup">
<div className="popup_inner">
<h2>Success!</h2>
<button className="close" onClick={togglePopup}>
Close me
</button>
</div>
</div>
) : null}
</div>
);
}
export default App;
React에서는 상태에 해당하는 데이터를 state로 따로 관리하고 싶어함.
React가 state를 통제할 수 있는 컴포넌트를 Controlled Component라고 함.
https://reactwithhooks.netlify.app/docs/forms.html
어떻게 React가 state를 통제할 수 있는가? → input에 값 입력 시, state도 그때그때 바뀌면(onChage)됨.
→ 데이터를 다룰 때는 컴포넌트들 간의 상호 관계와 데이터의 역할, 데이터의 흐름을 고려해 위치를 설정해야 함