오늘은 리액트의 핵심 State와 Props에 대해서 알아보겠다!
부자 관계로 된 컴포넌트 생성
function Parent() {
const itemOne = "React를";
const itemTwo = "배우고 있습니다.";
return (
<div className="parent">
<h1>I'm the parent</h1>
{/* Child의 props값 전달 */}
<Child text1={"I'm the eldest child"} />
<Child text2={`${itemOne} ${itemTwo}`} />
<Child />
</div>
);
}
function Child(props) {
return (
<div className="child">
{/* Child에 선언됐던 props값 실행 */}
<p>{props.text1}</p>
<p>{props.text2}</p>
</div>
);
}
export default Parent;
예시를 들어서 설명하겠다! 장바구니에 체크박스를 선택하면 바뀌어지는 예시다!
// 모듈 불러오기
import React, { useState } from "react";
function CheckboxExample() {
// state 호출 : 리턴값을 디스트럭처링하여 isC, setI 으로 사용, 변수명으로 써도 됨
// const stateHookArray = useState(false); // 디스트럭쳐링과 같음
// const isChecked = stateHookArray[0];
// const setIsChecked = stateHookArray[1];
const [isChecked, setIsChecked] = useState(false);
// const [state 저장 변수, state 갱신 함수] = useState(상태 초기 값);
// 이벤트 처리 : event.target.checked에 따라 결괏값 리턴
const handleChecked = (event) => {
setIsChecked(event.target.checked);
};
return (
<div className="App">
{/* DOM의 이벤트핸들러 : onChange로 값이 변하면 handleChecked 호출 */}
<input type="checkbox" checked={isChecked} onChange={handleChecked} />
{/* 불린데이터로 체크 됐는지 안됐는지 결과 */}
<span>{isChecked ? "Checked!!" : "Unchecked"}</span>
</div>
);
}
export default CheckboxExample;
state
선언 : useState()
사용, import { useState } from "react";
state
변수를 선언, useState()
형식으로 쓰는데 괄호 안엔 초깃값을 작성(state hook
)state
갱신(변경) : 1번째 리턴값 - setIsChecked
함수를 호출isCheck
변수에 적용, 갱신isCheck
를 리액트는 CheckboxExample()
에 다시 넘겨 다시 렌더링결론 : React 컴포넌트는 state가 변경되면 새로 호출 및 리렌더링됨, ⭐️가장 중요! 일반 데이터처럼 재할당이나 직접 수정(=V or .push(V) 등)을 한다면 적용되지 않음! 꼭꼭! 갱신 함수를 통해 변경하기!
DOM과 매우 비슷하다! 실제로 쓰는 언어 같은 것들을 공유하고 있는 경우가 많다!
<button onClick=handleEvent()>Event</button>
<button onClick={handleEvent}>Event</button>
이처럼 input
, button
등 쓰는 방식은 유사하기에 DOM에서 배웠던 걸 복습하고 이제 리액트의 갱신함수를 대입하여 쓰는 방식으로 공부해보자
<input>
<textarea>
<select>
와 같은 태그같이 사용자의 입력값을 제어하고 변경하는 엘리먼트에 자주 쓰이는 이벤트 핸들러다.
function NameForm() {
const [name, setName] = useState("");
const handleChange = (e) => {
// input 값 읽어오기 : target+value
setName(e.target.value);
}
return (
<div>
{/* onChange으로 텍스트가 변할 때마다 handleChange 발생 */}
{/* 이벤트 객체에 담긴 input(value)값을 새 state로 갱신해 출력 */}
<input type="text" value={name} onChange={handleChange}></input>
<h1>{name}</h1>
</div>
)
};
말그대로 클릭할 때마다 state
갱신
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>
);
export default function App() {
const [username, setUsername] = useState("");
const [msg, setMsg] = useState("");
return (
<div className="App">
<div>{username}</div>
<input
type="text"
value={username}
onChange={(event) => setUsername(event.target.value)}
placeholder="여기는 인풋입니다."
className="tweetForm__input--username"
></input>
<div>{msg}</div>
{/* TODO : 위 input과 같이 입력에 따라서 msg state가 변할 수 있게
아래 textarea를 변경하세요. */}
<textarea
placeholder="여기는 텍스트 영역입니다."
className="tweetForm__input--message"
onChange={(evernt) => setUsername(event.target.value)}
value={username}
></textarea>
</div>
);
}
이제 Twittler를 State와 Props에 맞게 설계해보자
- JSX 문법의 기본과 컴포넌트 기반 개발에 대해서 숙지
- React Router DOM으로 React에서 SPA(Single-Page Application)을 구현
- state hook을 이용하여, 컴포넌트에서 데이터를 변화
- props를 이용하여, 부모 컴포넌트의 데이터를 자식 컴포넌트로 전달
- 바람직한 컴포넌트 구조와 state와 props의 위치에 대해 고민
구조
├── /React Twittler State Props
│ ├── README.md
│ ├── /public # create-react-app이 만들어낸 파일
│ └── /src # React 컴포넌트
│ ├── static
│ │ └── dummyData.js
│ ├── Pages
│ │ ├── About.css
│ │ ├── About.js
│ │ ├── Mypage.css
│ │ ├── Mypage.js
│ │ ├── Tweets.css
│ │ └── Tweets.js
│ ├── Components # 추가! 단일 컴포넌트가 들어가는 폴더
│ │ ├── Tweet.css
│ │ └── Tweet.js
│ ├── App.css
│ ├── App.js
│ ├── Footer.js
│ ├── index.js
│ └── Sidebar.js
├ package.json
└ .gitignore