[CodeStates-Section2]U6.React State & Props

소이뎁·2022년 11월 30일
1

CodeStates_Frontend_42기

목록 보기
19/39

1.후기

  props와 states... 배운 것은 이해했는데 깊숙이 파고들면 많은 것들이 나온다는 것을 검색 몇 번만 해도 알 수 있었다. '내가 이걸 안다고 코드에 적용할 수 있을까?'라는 생각이 들었다. 실습이 더 필요한 파트이다.

2.새롭게 알게 된 것

Section2 Unit6 - [React] React State & Props
Chapter1. React State & Props
 -1. Props
 -2. State
 -3. 이벤트 처리
 -4. Controlled Component
 -5. React 데이터 흐름

<Chapter1. React State & Props>

출처: https://so-tired.tistory.com/78

1. Props(부모 -> 자식)

1) React Component 정의, React Component, Props

// React Component 정의
function Profile() {
	return (
	...
    )
}

// React Component
<Profile
	// Props 정의, Props는 객체
	name = '소플'
	introduction = '안녕하세요, 소플입니다'
	viewCount = {1500}
/>

2) Props란

컴포넌트에 전달할 다양한 정보를 가진 JavaScrip 객체
외부로부터 전달받은 값으로 컴포넌트의 속성(property)을 의미

3) Props의 특징

-read-only(값 변경 불가)

4) Props를 전달하는 방법1(속성값 전달)

부모 컴포넌트 안의 자식 컴포넌트에서 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>
  );
};

5) Props를 전달하는 방법2(태그 사이에 있는 값 전달)

-> 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/

2.State

1) State란

내부에서 변화하는 값(ex. 나이, 주소)
컴포넌트를 보고 무엇을 state로 관리할지 결정해야 함

2) useState 사용법

-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>

3) state 갱신하기

이벤트 발생 -> 이벤트 함수 실행 -> 이벤트 함수 안에 있는 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>
  );
}

4) 주의점

-state는 반드시 상태 변경 함수 호출로 변경해야 함.
-state가 변경되면 React 컴포넌트는 새롭게 호출되고, 리렌더링 됨.
-state가 참조자료형일 경우, 깊은 복사를 이용해 갱신해야 함. state의 주소가 바뀌지 않으면 state의 갱신을 React가 인식하지 못해 리렌더링 안 됨.

3.이벤트 처리

1) 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>

2) onChange

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

3) onClick

❌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()에 의해 업데이트 됨.

4.React 데이터 흐름

1) 애플리케이션 만드는 절차: 상향식(bottom-up)

: 컴포넌트 -> 조립 -> 전체 페이지
디자인 시안을 받으면, 가장 먼저 이를 컴포넌트 계층 구조로 나눠야 함

출처: https://www.kirupa.com/react/avoiding_unnecessary_renders.htm

-장점
테스트 쉬움
확장성이 좋음

-컴포넌트 구분 시 주의
단일 책임 원칙(하나의 컴포넌트는 한 가지 일만 함)에 따름

2) 데이터의 흐름: 하향식(top-down)

출처: https://www.nextree.io/react-props-6-3/

컴포넌트 바깥에서 props를 이용해 데이터를 마치 인자(arguments) 혹은 속성(attributes)처럼 전달받을 수 있음. 즉, 데이터를 전달하는 주체는 부모 컴포넌트. 이는 데이터 흐름이 하향식임을 의미.

참고. 리엑트는 단방향 데이터 흐름

출처: https://so-tired.tistory.com/78

3) state 구별법

(And 조건)
부모로부터 props를 통해 전달되지 않음
시간이 지나면 변할 수 있음
컴포넌트 안의 다른 state나 props를 가지고 계산 불가

ex. Twittler의 state 예시
사용자가 작성 중인 새로운 트윗 내용(이벤트에 따라 변함)
전체 트윗 목록(새 트윗 추가 기능)

4) state 위치

해당 State를 기반으로 동작하는 모든 컴포넌트의 상위 컴포넌트

ex. Twittler 예시
사용자가 작성 중인 트윗 내용 -> NewTweetForm
전체 트윗 목록 -> Twittler

<기타>

1.React, jsx 문법에서 중괄호를 사용하는 경우

import 시, export에 default가 없을 때
자바스크립트의 변수를 jsx 내부에(return(여기 안))서 사용할 때
자바스크립트 구문일 때
props 정의 시

2.객체의 key와 value가 같을 경우 축약 가능

// 일반
var o = {
  a: a,
  b: b,
  c: c
};

// 단축 속성명 (ES6)
var o = { a, b, c };

3.배열/객체의 구조분해할당

// 배열 -> 앞에서부터 순서대로
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 뒤에 바로 {}가 있음

4.Date.prototype.toLocaleDateString()

사용자 에이전트 시간대에서 지정된 날짜의 날짜 부분을 언어별로 표현한 문자열을 반환

// 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."

5.<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>

0개의 댓글