[05.22] React State&Props

0
post-thumbnail
  • Props
  • State
  • 이벤트 처리
  • React 데이터 흐름
  • 회고

📌 Props

Props란?

: 컴포넌트의 속성(property)/ 성별이나 이름처럼 변하지 않는 외부로부터 전달받은 값

Props의 특징

  • 우리가 어떠한 값을 컴포넌트에게 전달을 해줘야 할 때 사용
  • 부모 컴포넌트(상위 컴포넌트)로부터 전달받은 값
  • 어떤 타입의 값도 넣어 전달할 수 있도록 객체의 형태( { key : value } )를 가짐
  • 함부로 변경될 수 없는 읽기 전용 객체 → 읽기 전용 객체가 아니라면 props를 전달받은 하위 컴포넌트 내에서 props를 직접 수정시 props를 전달한 상위 컴포넌트의 값에 영항을 미칠수 있음 (의도치 않은 side effect 발생)

Props 사용 방법

  1. 하위 컴포넌트에 전달하고자 하는 값과 속성을 정의
  2. props를 이용하여 정의된 값과 속성을 전달
  3. 전달받은 props를 렌더링

[예시]

//parent(부모컴포넌트)와 child(자식컴포넌트) 컴포넌트 선언 
function Parent() {
	return (
		<div className="parent">
			<h1>I'm the parent</h1>
			//속성 및 값을 할당하기
			<Child text={"I'm the eldest child"}/>
		</div>
	);
};

//<parent> 컴포넌트에서 전달한 문자열을 받아보기 위해 props를 전달받고
//렌더링을 위해 props라는 객체의 value에 접근해야 하는데 이때 dot notation을 사용한다.
function Child(props) {
	return (
		<div className="child">
			<p>{props.text}</p>
		</div>
	);
};
  • React에서 JSX 속성 및 값을 할당하는 방법 1
    <Child attribute={value}/>
  • React에서 JSX 속성 및 값을 할당하는 방법 2
    <Child text={"I'm the eldest child"}/>

Props.children

: 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>
  );
};

📌 State

State(상태)란?

  1. 컴포넌트의 사용 중 컴포넌트 내부에서 변할 수 있는 값/ 감정과 나이처럼 변할 수 있는 값

  2. 객체가 특정 상태에 따라 행위를 달리하는 상황에서 상태를 조건문으로 검사해서 행위를 달리하는 것이 아닌, 상태를 객체화하여 상태가 행동 할 수 있도록 위임하는 패턴(변화를 준다는 것)

    ex) 시계가 있다고 가정하면, state로는 현재 시간을 나타낼 수 있으며, useState를 사용해서 컴포넌트의 상태를 간편하게 생성하고 업데이트를 해주는 도구가 됨

State의 특징

  • 상태에 따라 변화
  • 직접 변경이 가능
  • state가 변경되면 컴포넌트를 다시 렌더링 해야함
  • 외부에는 비공개, 컴포넌트 스스로가 관리

useState 사용법

  1. React로부터 useState 불러오기

    import {useState} from "react";
  2. useState를 호출하면 배열을 반환

    const [state 저장 변수, state 갱신 함수(setstate)] = useState(상태 초기 값);
  3. 실제 코드로 작성하기

    • isChecked : state를 저장하는 변수
    • setIsChecked : isChecked를 변경하는 함수
    • useState : state hook
    • false : state 초깃값
    function CheckboxExample() {
    	const [isChecked, setIsChekec] = useState(false);
    	//handlechecked : 체크박스의 변경 이벤트를 처리하는 콜백함수
    	//event객체를 매개변수로 받아와서 체크박스의 현재 체크 여부를 나타내는 불리언값
    	const handleChecked = (event) => {
    	setIsChecked(event.target.checked);
    };
    
    // JSX를 사용하여 컴포넌트의 렌더링 결과를 정의
    return (
    	<div className="App">
    		/*input의 type 속성은 checkbox로 설정 
    		checked는 isChecked를 변수로 설정하여 현재 체크 여부 반영
    		onChange 속성에는 handleChecked 함수로 체크박스의 변경 이벤트를 처리*/
    		<input type="checkbox" checked={isChecked} onChange={handleChecked}/>
    		//isChecked의 true,false를 구분하는 조건문
    		<span>{isChecked ? "Checked!" : "Unchecked"}</span>
    	</div>
    	);
    }
  4. useState 초기값

    : useState의 초기값이 무거운 값을 가져온다면 렌더링 될때마다 무거운 값이 계속 렌더링이 된다.

    바로 안에 값을 바로 넣어주기 보다는 콜백함수로 값을 넣어줘서 최초에 한번만 렌더링 되도록한다.

    import { useState } from 'react';
    
    const heavyWork = () => {
    	return ['홍길동','김민수'];
    };
    
    function App () {
    	const [names, setNames] = useState(() => {
    		return heavyWork();
    	});
    ...이하 생략
    // 출처 : 유튜버 별코딩 useState 사용

📌  이벤트 처리

이벤트 처리 방식

  • React에서 이벤트는 소문자 대신 카멜케이스 사용
  • JSX를 사용하여 문자열이 아닌 함수로 이벤트 처리 함수를 전달

[예시1_HTML에서 이벤트 처리방식]

<button onClick="handlEvent()">Event</button>

[예시2_React의 이벤트 처리방식]

<button onClick={handleEvent}>Event</button>

onChange

function NameForm() {
	const[name, setName] = useState("");

	const handleChange = (e) => {
		setName(e.target.value);
	}

	return (
		<div>
		/*onChange는 input의 텍스트가 바뀔때마다 발생하는 이벤트
		이벤트가 발생하면 handleChange 함수가 작동하며, 이벤트객체에 담긴 input값을 setState를
		통해 새로운 state로 변경*/
			<input type="text" value={name} onChange={handleChange}></input>
			<h1>{name}</h1>
		</div>
	)
};

onClick

: 사용자가 클릭이라는 행동을 했을 때 발생하는 이벤트

function NameForm() {
	const [name, setName] = useState("");
	
	const handleChange = (e) => {
		setName(e.target.value);
	}
	
	return (
		<div>
			<input type="text" value={name} onChange={handleChange}></input>
			//button 클릭시 input에 작성한 이름이 alere을 통해 알림 창이 팝업되도록 코드를 추가
			<button onClick={alert(name)}>Button</button>
			<h1>{name}</h1>
		</div>
	);
};

Select

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 tag 엘리먼트를 사용해서 목록에 있는 옵션을 선택하면 값이 state변수에 변경
      <select onChange={handleFruit}>{options}</select>
      <h3>You choose "{choice}"</h3>
    </div>
  );
}

Pop up

function App() {
  const [showPopup, setShowPopup] = useState(false);

  const togglePopup = () => {
		//팝업창의 열림과 닫힘을 제어하기 위해서 논리 부정 연산자를 사용
    setShowPopup(!showPopup)
  };

  return (
    <div className="App">
      <h1>Fix me to open Pop Up</h1>
			// open me 버튼을 클릭했을때 팝업창이 열리도록
      <button className="open" onClick={togglePopup}>Open me</button>
			// 삼항연산자에 null의 값은 showPopup이 거짓일때 null이 반환되어 해당 부분이 렌더링
			되지 않게 설정
      {showPopup ? (
        <div className="popup">
          <div className="popup_inner">
            <h2>Success!</h2>
						//close me 버튼을 눌렀을때 열린 팝업창이 닫히도록
            <button className="close" onClick={togglePopup}>
              Close me
            </button>
          </div>
        </div>
      ) : null}
    </div>
  );
}

📌  React 데이터의 흐름

React의 흐름

: 단방향 데이터 흐름(one-way data flow)

→ 컴포넌트의 구조를 짤 경우 : 상향식

(PM, UX디자이너로부터 앱의 디자인을 전달받고 컴포넌트 계층구조를 나눈것이 first)

state의 위치

  • 두개의 자식 컴포넌트가 하나의 상태에 접근하고자 할 때는 두 자식의 공통 부모 컴포넌트 상태의 위치를 고려 (데이터의 흐름을 고려하여 설정해줌)

🙋🏻‍♀️회고

수업 진도를 나갈때는 그냥 어림잡아 이해를 하다가 블로깅하면서 복습을 하니 더 이해가 갔다

내일은 과제를 다시 풀어보면서 복습하고 더 파고들어서 이해를 시켜버려야겠💪🏻

0개의 댓글