props와 states... 배운 것은 이해했는데 깊숙이 파고들면 많은 것들이 나온다는 것을 검색 몇 번만 해도 알 수 있었다. '내가 이걸 안다고 코드에 적용할 수 있을까?'라는 생각이 들었다. 실습이 더 필요한 파트이다.
Section2 Unit6 - [React] React State & Props
Chapter1. React State & Props
-1. Props
-2. State
-3. 이벤트 처리
-4. Controlled Component
-5. React 데이터 흐름
출처: https://so-tired.tistory.com/78
// React Component 정의
function Profile() {
return (
...
)
}
// React Component
<Profile
// Props 정의, Props는 객체
name = '소플'
introduction = '안녕하세요, 소플입니다'
viewCount = {1500}
/>
컴포넌트에 전달할 다양한 정보를 가진 JavaScrip 객체
외부로부터 전달받은 값으로 컴포넌트의 속성(property)을 의미
-read-only(값 변경 불가)
부모 컴포넌트 안의 자식 컴포넌트에서 props 정의
-> 자식 함수형 컴포넌트에서 props를 인자로 받음
-> 부모 컴포넌트 안의 자식 컴포넌트에서 정의한 모든 props가 객체로 들어옴(부모 컴포넌트에 3개의 자식 컴포넌트를 넣었다면 객체도 3개가 들어옴)
-> 자식 컴포넌트 안에서 "props.key이름"으로 사용할 수 있음
여러 객체 들어오는 예시.
출처: https://devbirdfeet.tistory.com/111
Props 전달 예시.
// React에서 JSX 속성 및 값을 할당하는 방법
function Parent() {
return (
<Child text={"I'm the eldest child"} />
)
}
// <Child> 컴포넌트에서 props.text 렌더링 예시
function Child(props) {// props에 객체 1개 들어옴
return (
<div className="child">
<p>{props.text}</p> // "I'm the eldest child"
</div>
);
};
-> props.children
function Parent() {
return (
<div className="parent">
<h1>I'm the parent</h1>
<Child>I'm the eldest child</Child>
</div>
);
};
function Child(props) {// props에 객체 1개 들어옴
return (
<div className="child">
<p>{props.children}</p> // "I'm the eldest child"
</div>
);
};
참고 사이트: https://www.nextree.io/react-props-6-3/
내부에서 변화하는 값(ex. 나이, 주소)
컴포넌트를 보고 무엇을 state로 관리할지 결정해야 함
-useState 불러오기
import { useState } from "react";
-state 저장 변수, 갱신 함수 할당
❌jsx 구문 안
✅컴포넌트 안
const [state 저장 변수, state 갱신 함수] = useState(상태 초깃값);
예시.
function CheckboxExample() {
// state 저장 변수 선언, 배열 구조분해할당
const [isChecked, setIsChecked] = useState(false);
}
참고. state 저장 변수 특징
변수 이름 자유
React에 의해 함수가 끝나도 사라지지 않음.
참고. state 갱신 함수
비동기 함수
전달 인자로 콜백 함수를 받을 수도 있음
-state 사용하기
예시.
// javascript 구문이므로 중괄호 사용
<span>{isChecked ? "Checked!!" : "Unchecked"}</span>
이벤트 발생
-> 이벤트 함수 실행
-> 이벤트 함수 안에 있는 state 갱신 함수 실행
-> state 갱신
(-> 컴포넌트 재호출, 리렌더링
-> return 문 안의 삼항조건문 실행
-> 출력값 변경
)
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>
);
}
-state는 반드시 상태 변경 함수 호출로 변경해야 함.
-state가 변경되면 React 컴포넌트는 새롭게 호출되고, 리렌더링 됨.
-state가 참조자료형일 경우, 깊은 복사를 이용해 갱신해야 함. state의 주소가 바뀌지 않으면 state의 갱신을 React가 인식하지 못해 리렌더링 안 됨.
-React 에서 이벤트는 소문자 대신 카멜 케이스(camelCase) 사용(ex. onChange, onClick)
-함수값이 아닌 함수를 할당
예시1. HTML과 React 이벤트 처리 비교
// HTML
<button onclick="handleEvent()">Event</button>
// React
<button onClick={handleEvent}>Event</button>
예시2. React 이벤트 처리
// ✅onClick = 함수
<button onClick={plusNumber}>Plus</button>
// ❌onClick = 함수의 리턴값
<button onClick={plusNumber()}>Plus</button>
// ❌onClick = 함수를 리턴하는 함수
<button onClick={() => plusNumber}>Plus</button>
function NameForm() {
// 배열 구조분해할당으로 name, setName에 useStaet 리턴값 할당
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>
)
};
참고.
<input>
에 value 속성 넣어주는 이유
: 초기화했을 때 값을 받아오기 위해서
참고 사이트: https://sso-feeling.tistory.com/468
참고 사이트: https://react.vlpt.us/basic/08-manage-input.html
❌onClick 이벤트에 함수값 전달
✅onClick 이벤트에 함수 전달
function NameForm() {
// 배열 구조분해할당으로 name, setName에 useStaet 리턴값 할당
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>
);
};
참고. Controlled Component(제어 컴포넌트)
React에 의해 값이 제어되는 입력 폼 엘리먼트. 사용자의 입력을 기반으로 자신의 state를 관리하고 업데이트함. React에서는 변경할 수 있는 state가 일반적으로 컴포넌트의 state 속성에 유지되며 setState()에 의해 업데이트 됨.
: 컴포넌트 -> 조립 -> 전체 페이지
디자인 시안을 받으면, 가장 먼저 이를 컴포넌트 계층 구조로 나눠야 함
출처: https://www.kirupa.com/react/avoiding_unnecessary_renders.htm
-장점
테스트 쉬움
확장성이 좋음
-컴포넌트 구분 시 주의
단일 책임 원칙(하나의 컴포넌트는 한 가지 일만 함)에 따름
출처: https://www.nextree.io/react-props-6-3/
컴포넌트 바깥에서 props를 이용해 데이터를 마치 인자(arguments) 혹은 속성(attributes)처럼 전달받을 수 있음. 즉, 데이터를 전달하는 주체는 부모 컴포넌트. 이는 데이터 흐름이 하향식임을 의미.
참고. 리엑트는 단방향 데이터 흐름
출처: https://so-tired.tistory.com/78
(And 조건)
부모로부터 props를 통해 전달되지 않음
시간이 지나면 변할 수 있음
컴포넌트 안의 다른 state나 props를 가지고 계산 불가
ex. Twittler의 state 예시
사용자가 작성 중인 새로운 트윗 내용(이벤트에 따라 변함)
전체 트윗 목록(새 트윗 추가 기능)
해당 State를 기반으로 동작하는 모든 컴포넌트의 상위 컴포넌트
ex. Twittler 예시
사용자가 작성 중인 트윗 내용 -> NewTweetForm
전체 트윗 목록 -> Twittler
import 시, export에 default가 없을 때
자바스크립트의 변수를 jsx 내부에(return(여기 안))서 사용할 때
자바스크립트 구문일 때
props 정의 시
// 일반
var o = {
a: a,
b: b,
c: c
};
// 단축 속성명 (ES6)
var o = { a, b, c };
// 배열 -> 앞에서부터 순서대로
const [a, b] = [1, 2, 3, 4] // a = 1, b = 2
// 객체-경우1. '키 = 키:값'일 경우 -> 키 = '동일한 키'의 값
const {a, b, x} = {a:3, b:5, c:6, d: 1}// a = 3, b = 5, x = undefined
// 객체-경우2.'키:값 = 키:값'일 경우 -> 앞의 값 = 뒤의 값
var {p: foo, q: bar} = {p: 42, q: true} // foo = 42, bar = true
예시.
// 부모 컴포넌트
return(
<ul className='tweets'>
{tweetsList.map((el) => {
return <Tweet tweet={el} key={el.id} />;
})}
</ul>
)
//자식 컴포넌트
// 객체 구조분해할당: {tweet} = {tweet: el, key: el.id} // tweet = el
const Tweet = ({ tweet }) => {
const parsedDate = new Date(tweet.createdAt).toLocaleDateString('ko-kr');
return (
...
);
};
참고. 구조분해할당인지 아는 법
(or 조건)
함수 인자에 '{변수명}'이 있음
var/let/const 뒤에 바로 {}가 있음
사용자 에이전트 시간대에서 지정된 날짜의 날짜 부분을 언어별로 표현한 문자열을 반환
// US English -> 월/일/년
console.log(date.toLocaleDateString("en-US"));
// "12/20/2012"
// British English -> 일/월/년
console.log(date.toLocaleDateString("en-GB"));
// "20/12/2012"
// Korean uses -> 년/월/일
console.log(date.toLocaleDateString("ko-KR"));
// "2012. 12. 20."
<select>
, <option>
, <label>
// 코드
<label for="pet-select">Choose a pet:</label>
<select id="pet-select">
<option value="">--Please choose an option--</option>
<option value="dog">Dog</option>
<option value="cat">Cat</option>
<option value="hamster">Hamster</option>
<option value="parrot">Parrot</option>
<option value="spider">Spider</option>
<option value="goldfish">Goldfish</option>
</select>