BEB 07 3-1

Donghun Seol·2022년 9월 26일
0

코드스테이츠 BEB 07

목록 보기
9/39

State & Props

State : 변할 수 있는 것, 컴포넌트 내부에서 변화 가능
Props : 외부로 부터 전달받은 값

<Human /> 컴포넌트의 state와 props

  • states : 나이, 사는 곳,
  • props : 성별, 부모님, 태어난 곳

props

property, 상위 컴포넌트로부터 전달받은 값으로 변하지 않음
object 형태
읽기 전용, 단방향, 하향식 데이터 흐름 원칙을 지켜야 함.
사용법

  • 태그 내에 속성명, 속성값으로 아래와 같이 삽입한다.
  • 태그 사이에 넣는 방법도 있다.(props.children 으로 접근)
  • 이벤트 핸들러를 prop로 전달하고, 인라인 익명함수로 작성하기도 한다.
  • props로 객체를 전달하기 위해서는 {...someObj} 형식으로 전달해야한다.
<Child attribute={value} />

function Child(props) {
  return (
    <div className="child"></div>
  );
};

state

리액트에서 state를 다루기 위해 useState(<initVal>)라는 함수를 활용한다.
상태값이 primitive value와 객체인 경우에 setState하는 방식이 다름을 잘 기억하자.

  • primitive 밸류는 직관적으로 setState하면 되지만,
  • 배열이나 객체의 경우, spread operator로 얕은 복사 한 다음 재할당 해주어야 한다.
    objState = {...objState, newElem}
    arrState = [...arrState, newElem}

리액트의 가상 DOM은 '차이점'을 기준으로 렌더링 한다.
객체는 포인터로 저장되고, Array.prototype.push 등의 메서드는
포인터를 변화시키지 않으므로, 상태변화를 리액트가 인지하지 못하기 때문이다.

import { useState } from "react";

// 풀어쓴 코드
const stateHookArray = useState(false);
const isChecked = stateHookArray[0];
const setIsChecked = stateHookArray[1];

// 구조분해 할당을 통한 단축코드
const [isChecked, setIsChecked] = useState(false);

state 변경시 주의할 점

항상 상태변경 함수 호출로 상태변경해야한다.

showPopup 막혔던 부분, set State 함수 활용법

import React, { useState } from "react";
import "./styles.css";

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

  const togglePopup = (event) => {
    console.log(showPopup);
    setShowPopup(!showPopup);
  };

  return (
    <div className="App">
      <h1>Fix me to open Pop Up</h1>
      <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;

나만의 컴포넌트에 적용해보기

반복문을 통해 생성하는 컴포넌트에 key 속성을 넣는 것 잊지 않기
어떤 컴포넌트를 대상으로 state, props관리를 해야되는지 잘 고려하기


//main 컴포넌트
import { dummyTweets } from './dummyData';
import SingleTweet from './SingleTweet';

function Main() {
    return (
        <div className='Main'>
            <ul>
                {dummyTweets.map(elem => <SingleTweet key={elem.id} value={elem} />)}
            </ul>
        </div>
    );
}
export default Main; 

// 상태관리와 이벤트리스너가 적용된 singleTweet 컴포넌트
import React, { useState } from 'react';

function SingleTweet(props) {
    const [isActive, setActive] = useState(true);

    const handleTweetClick = (event => {
        console.log(event);
        setActive(!isActive);
    });
    const { item_id, username, content } = props.value;
    return (
        <div style={{
            border: "solid 1px black",
            backgroundColor: isActive ? 'green' : 'gray'
        }} className='singleTweet' onClick={handleTweetClick}>
            <p>{item_id} </p>
            <p>{username} </p>
            <p>{content} </p>
        </div>
    );
}
export default SingleTweet; 

기타 학습한 내용

velog 서버가 잠시 터져서 vscode 설정을 업데이트 했다.

  1. emmet을 jsx에 활용가능하게 설정함
  2. vim surround plugin 사용법 다시 익힘
  • S + t 입력한뒤 괄호 말고 태그명만 입력하면 깔끔하게 태그로 감쌀 수 있다
  1. vim easymotion plugin 설정함
  • <leader><leader> + <w|b|f|F> 입력하면 vimium에서 점프하는 것처럼 이동가능.

Advance 구현및 추가 학습한 내용

스프린트 테스트에 오류가 있어 잠깐 멘붕했지만, 그래도 쭈욱 advanced까지 구현해보았다.

객체 배열에서 객체들의 특정 키값만 추출하기

arr = [{name:"kim", age:20}, {name:"lee", age:50}]

arr.map(elem => elem.name) ["kim", "lee"]

시간을 킷값으로 받기 위해 현재시간을 구하기

데이터의 길이로 키를 설정하니 삭제시 문제발생함.

Date.now();// 1664196074967

Advance Challenge

옵션으로 필터링하는 기능
함수를 분리해도 되지만 간단히 한번만 사용할 로직이므로 인라인함수로 넣었다.
일부러 배운 내용을 활용하기 위해 reduce를 활용해서 구현해 보았다.

<div className="tweetForm__filter">필터
  <select defaultValue='all' name="select" onChange={event => setSelected(event.target.value)}>
  <option value="all">ALL</option>
  {props.dummyTweets.reduce((acc, val) => {
    if (!acc.includes(val.username)) {
      acc.push(val.username);
    }
    return acc;}, []).map((elem, index) => <option key={index} value={elem}>{elem}</option>)}
  </select>
</div>

// tweets ul에 기본으로 필터링하는 로직을 selected 상태와 함께 삽입했다.
// 필터가 없으면 항상 모든 트윗을 보여준다.
<ul className="tweets">
{props.dummyTweets.filter(elem => selected === 'all' ? true : elem.username === selected).map((elem) => <Tweet key={elem.id} tweet={elem} />)}
</ul>

트윗 삭제하는 기능, filter 활용하니 깔끔하게 구현됨

<div className="Btn-Wrapper">
  <button className="tweetForm__submitButton" onClick=
    {event => setTweetData(dummyTweets.filter(elem => elem.id !== tweet.id))}>
  트윗 삭제
  </button>
</div>
profile
I'm going from failure to failure without losing enthusiasm

0개의 댓글