React state & props

0

REACT

목록 보기
3/12
post-thumbnail

혹시나 잘못된 개념 전달이 있다면 댓글 부탁드립니다. 저의 성장의 도움이 됩니다

오늘의 Checkpoint

// 상위 컴포넌트
function Tweets(){
	return (
        <ul className="container">
            <UserLeeTweet />
        	<UserParkTweet />
        </ul>
	);
}

// 하위 컴포넌트 : 동일한 구조 내용만 다름
function UserLeeTweet(){
	return (
    	<li>OO의 게시글
        	<p>: 안녕하세요</p>
        </li>
    );
}
function UserParkTweet(){
	return (
    	<li>OO의 게시글
        	<p>: hello</p>
        </li>
    );
}

Props

컴포넌트의 속성값(property)으로 함수의 전달인자처럼 상위 컴포넌트에서 하위 컴포넌트로 값을 전달하여 동일한 컴포넌트로 다양하게 표현할 수 있음
-> 처음 렌더링 될 때, 컴포넌트의 초기값으로 사용

  • 객체 형태
  • 변하지 않는 값, read-only
    -> 리엑트의 특성 중 단방향, 하향식 데이터 흐름 원칙과 일치 (side effect 방지)
  • 여러개의 속성 지정 가능
<Child attribute={value} />
// props(객체)의 key로 하위 컴포넌트의 속성, value는 속성값 적용
// 상위 컴포넌트
function Tweets(){
  	const userLee = "이OO"
    const userPark = "박OO"
	return (
        <ul className="container">
            <Tweet name={userLee} shortmsg={"안녕하세요"} /> 
        	<Tweet name={userPark} shortmsg={"hello"} />
        	{/* 전달하는 값을 속성으로 표기*/}
        </ul>
	);
}

// 하위 컴포넌트 : 전달인자로 객체 사용 -> 하나의 컴포넌트로 재활용 가능
function Tweet(props){
	return (
    	<li>{props.name}의 게시글
        	<p>{": " + props.shortmsg}</p>
        </li>
    );
}

구조분해할당과 Props

// <Tweet name={"이OO"} shortmsg={"안녕하세요"} />

function Tweet( { name, shortmsg } ){
	return (
    	<li>{name}의 게시글
        	<p>{": " + shortmsg}</p>
        </li>
    );
}

/*---- props은 {name:"이OO", shortmsg:"안녕하세요" } ----*/
// let {name, age} = props

// let name = props.name;
// let shortmsg = props.shortmsg

props.children

: <Child> message to props</Child> 처럼 열고 닫는 컴포넌트 태그 안에 전달할 내용을 넣으면 하위컴포넌트에서 children 속성값으로 접근 가능

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


// 상위 컴포넌트
function Tweets(){
  const userLee = "이OO"
  const userPark = "박OO"
  return (
      <ul className="container">
        <Tweet> {userLee}{"안녕하세요"} </Tweet> 
        <Tweet>{userPark}{"hello"}</Tweet>
        {/* 열고 닫는 컴포넌트 안에 전달할 내용 기입 */}
      </ul>
  );
}

// 하위 컴포넌트 : 전달인자로 객체 사용
function Tweet(props){
  return (
    <li>
      <p>{props.children}</p>
    </li>
  );
}



State

컴포넌트 속에서 이벤트에 의해 변화하는 값
-> state가 변경되면 자동으로 리렌더링

useState

State hook으로 react에서 state를 다루는 방법 중 하나로 사용되는 특별한 함수
cf. React 16.8 버전부터 Hook이 추가되어 함수형 컴포넌트에서도 state를 변경 가능

  • 호출 후 사용
  • 길이 2의 배열을 반환
    const [ state , setState ] = useState(defalt);
    • 0번째 인덱스 : state 저장 변수
    • 1번째 인덱스 : state를 변경하는 함수 -> 이벤트에 함수에서 사용
    • 전달인자 : state의 초기값으로 설정할 값 입력

  1. 호출

    import { useState } from "react";
  2. state 변수 선언
    : 컴포넌트 내부에서 useState 호출 -> 함수 종료되어도 변수 사라지지 않음

    /* isChecked가 state며 기본값은 false로 설정 */
    
    // case 1
    const [isChecked, setIsChecked] = useState(false);
    
    // case 2
    const stateHookArray = useState(false); 
    const isChecked = stateHookArray[0];
    const setIsChecked = stateHookArray[1];
  3. state 변경
    : 2에서 선언한 'state 변경함수'를 호출하여 state값 갱신
    -> 'state 변경함수'의 전달인자는 변경될 state값을 의미

    import React, { useState } from "react";
    
    function CheckboxExample() {
      const [isChecked, setIsChecked] = useState(false);
    	
      /*--- 이벤트에 의해 state 변경----*/
      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 변수 사용
    : { } 속에 넣어서 JSX 내부에 변경사항 반영되도록 코드 수정
    ex. <span>{isChecked ? "Checked!!" : "Unchecked"}</span>


state를 상태 변경 함수 대신 강제로 변경한다면

React에서는 state를 State hook을 통해서 변경할 수 있도록 정의되어있기 때문에 임의로 변경하는 코드를 작성하면 리렌더링 되지 않거나 state가 변경되지 않음

const forcefullyhandleChecked = (event) => {
	isChecked = true; 
  	// 강제 변경으로는 리렌더링 되지 않음
    // state.push(1);
    // state[1] = 2;
    // state = 'wrong state';
};


React의 이벤트 처리

  • camelCase 적용
    cf. DOM의 이벤트 처리는 소문자

  • JSX 속에서 { } 로 Event handler 전달

    /*---- React ----*/
    <button onClick={handleEvent}>event</button>
    
    /*---- DOM ----*/
    <button onclick="handleEvent()">event</button>

onChange

<input>, <textarea>, <select> 와 같은 Form 요소의 사용자 입력값이 변경되면 발생하는 이벤트
-> Event 객체에 event.target.value 방식으로 입력값을 추출할 수 있음


onClick

<button>, <a> 와 같은 클릭 가능한 요소에 발생하는 이벤트

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

  /*---- onChange에 적용된 이벤트 핸들러 ----*/
  const handleChange = (e) => {
    setName(e.target.value);
  }
  
  /*
  // 이벤트 핸들러 함수 선언한 경우 -> {handleClick} 로 전달
  const handleClick = ()=>{
  	alert(name);
  }
  */

  return (
    <div>
      <input type="text" value={name} onChange={handleChange}></input>
      {/*---- onClick에 적용된 이벤트 핸들러 ----*/}
      {/*<button onClick={handleClick}>Button</button>*/}
      <button onClick={() => alert(name)}>Button</button>
      <h1>{name}</h1>
    </div>
  );
};

Quiz

import React, { useState } from "react";

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

  const togglePopup = (event) => {
    // Pop up 의 open/close 상태에 따라
    // 현재 state 가 업데이트 되도록 함수를 완성하세요.
    setShowPopup((event.target.className ==="open")? true: false)
  };

  return (
    <div className="App">
      <h1>Fix me to open Pop Up</h1>
      {/* 버튼을 클릭했을 때 Pop up 의 open/close 가 작동하도록
          button tag를 완성하세요. */}
      <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;


Controlled Component

React가 state를 통제할 수 있는 컴포넌트
: input값이 바뀔때(onChange)마다 state가 변경되고, input의 value가 변경된 state와 같음
-> 변한 값과 대상의 값이 같아지게 설정

import React, { useState } from "react";

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={(event) => {setMsg(event.target.value)}}
        value={msg} {/*<----- 변경된 값과 동기화*/}
      ></textarea>
    </div>
  );
}



오늘의 나

느낀점
오늘 오전에 카페 가느라 페어때문에 조용한 곳으로 이동하느라 정신없어서 개념학습의 튜토리얼을 다 못한상태로 과제를 진행했는데, 리엑트 더 복습해야겠다. 주말에 블로그 정리 다 해서 그래도 사용할 줄알았는데 이번문제에 map()위치가 또 난항이었다... 아질 갈길이 멀구나. 제공한 틀에서 테스트 통과하려면 부분적으로 수정해야하는데 이게 어느정도까지 수정을 해야하는지 감이 안와서 조금 더 헷갈리는 것 같다. 그런데 이게 내가 확실하게 알고있으면 이런게 덜할테지. 더 집중해야지. 그리고 DOM이벤트...!!! 이번 주말은 이거다. 강의 찾아보고, 정리못한 내용 다시 작업해서 확실히 알고 넘어가자.

개선점 및 리마인드

수면시간 확보

요즘 다시 수면시간이 어그러졌다. 못해서 더 잡고있어봤자 정신이 몽롱하면 도루묵이다. 마라톤 생각하자!!

**

0개의 댓글