[Modern React with Redux] 00 주말 리액트 복습

9rganizedChaos·2021년 6월 6일
2
post-thumbnail

벨로퍼트와 함께 하는 모던 리액트의 코드를 따라 쳐보며 주말동안 리액트를 복습!
사실 부트캠프 수료 후, 과제를 하고 또 복습을 하며, 리액트를 정말 수박 겉핥기 식으로만 알고 있었다는 걸 다시 한 번 실감한다.

Fragment

리액트에서는 JSX문법을 사용하기 때문에, return문 안쪽의 태그들을 꼭 하나의 태그로 감싸줘야 한다! 그럴 때 별 의미없는 <div>를 남발하기 마련이다. 이 때 사용하는 것이 바로 React.fragment이다.

class Columns extends React.Component {
  render() {
    return (
      <React.Fragment>
        <td>Hello</td>
        <td>World</td>
      </React.Fragment>
    );
  }
}

사실 fragment를 이미 사용하고 있었는데, fragment의 단축문법은 아래와 같다.

class Columns extends React.Component {
  render() {
    return (
      <>
        <td>Hello</td>
        <td>World</td>
      </>
    );
  }
}

defaultProps

프롭스 전달 값이 없는 경우에도 기본값을 넣어주고 싶을 때는 아래와 같이 defaultProps를 이용한다! 컴포넌트 자체의 속성값으로 넣어준다!

import React from "react";

function Hello({ color, name }) {
  return <div style={{ color }}>안녕하세요 {name}</div>;
}

Hello.defaultProps = {
  name: "이름없음",
};

export default Hello;

props.children

태그 안쪽으로 전달한 props를 조회하기 위해 props.children이란 문법을 사용하는 건 이미 알고 있었는데, 아래와 같이 문자열이 아닌, 태그들 자체를 전달하는 건 처음 봤다.

궁금한 건 왜 이런 식으로 코드를 작성하냐는 것...

import React from 'react';
import Hello from './Hello';
import Wrapper from './Wrapper';

function App() {
  return (
    <Wrapper>
      <Hello name="react" color="red"/>
      <Hello color="pink"/>
    </Wrapper>
  );
}

export default App;
import React from 'react';

function Wrapper({ children }) {
  const style = {
    border: '2px solid black',
    padding: '16px',
  };
  return (
    <div style={style}>
      {children}
    </div>
  )
}

export default Wrapper;

삼항연산자 대신 &&연산자 사용하기

특정 조건이 true 이면 보여주고, 그렇지 않다면 숨겨주는 단순한 상황에서는 && 연산자를 사용해서 처리하는 것이 더 간편하다.

import React from 'react';

function Hello({ color, name, isSpecial }) {
  return (
    <div style={{ color }}>
      {isSpecial && <b>*</b>}
      안녕하세요 {name}
    </div>
  );
}

Hello.defaultProps = {
  name: '이름없음'
}

export default Hello;

props 값 설정을 생략하면 ={true}

그렇다고 합니다...

함수형 업데이트

useState setter함수 이용할 때, 특정 값을 넣어줄 수도 있지만, 함수를 넣어줄 수도 있다.

import React, { useState } from 'react';

function Counter() {
  const [number, setNumber] = useState(0);

  const onIncrease = () => {
    setNumber(prevNumber => prevNumber + 1);
  }

  const onDecrease = () => {
    setNumber(prevNumber => prevNumber - 1);
  }

  return (
    <div>
      <h1>{number}</h1>
      <button onClick={onIncrease}>+1</button>
      <button onClick={onDecrease}>-1</button>
    </div>
  );
}

export default Counter;

useState하나로 여러 개 상태 관리

하나의 객체로 묶어서 상태관리해주기!

function InputSample() {
  const [inputs, setInputs] = useState({
    name: '',
    nickname: ''
  });

useRef

리액트에서 DOM조작하기!
글로벌 선택자 대신 ref를 이용해야 한다는 것은 알고 있지만, 아직도 왜인지 정확하게 이해하고 있지는 못하고 있다. 짐작컨데!
1) 컴포넌트로 인스턴스 여러 개 만들었을 때 글로벌 선택자로 선택할 시에 의도한 엘리먼트를 제대로 선택하지 못할 수 있기 때문
2) 렌더링 순서와 관련한 문제!
3) 매번 렌더링 새로 될 때 초기화(?)

모쪼록 useRef()를 이용하면 함수컴포넌트에서 쉽게 ref객체를 만들수 있다. 이 객체는 우리가 선택하고 싶은 DOM에 ref값으로 설정해줘야 한다. 그러면 Ref 객체의 .current 값은 우리가 원하는 DOM을 가르키게 된다.

왜 map 돌릴 때 key를 작성해야 하는가

이거 늘 의문이었다. 대체 왜 key를 작성해줘야 하는가!
옛날에 자료구조 공부할 때 배열과 연결리스트 공부할 때와 비슷한 느낌이었다!
key가 있다면, 기존 인스턴스들을 그대로 두고 수정, 삭제, 추가할 수 있는데, key가 없다면, 최악의 경우 전부 다 삭제하고 새로 렌더링 해야 할 수 있다.

변수관리를 위한 useRef 활용!

const nextId = useRef(4);
  const onCreate = () => {
    // 나중에 구현 할 배열에 항목 추가하는 로직
    // ...

    nextId.current += 1;

이런 식으로 활용이 가능하다!
중요한 사실은 useRef로 관리하는 변수는 useState로 선언한 상태와 달리 값이 바뀌어도 컴포넌트가 리렌더링되지 않는다. 특히 useRef로 관리하는 변수는 설정하고 바로 조회가 가능하다. (상태와 같은 경우는 setter함수 호출하고 렌더링이 돼야 업데이트된 상태 조회가 가능하다.)

내가 했던 실수... useRef 쓸때는 .current를 써야 함을 잊지 말자...

useEffect에서 deps 파라미터 생략하면!

컴포넌트가 리렌더링 될 때마다 호출이 된다!
[] 빈 배열 넣으면 처음에 한 번 만!
요소가 들어간 배열 넣으면 해당 요소가 업데이트 될때마다 호출

profile
부정확한 정보나 잘못된 정보는 댓글로 알려주시면 빠르게 수정토록 하겠습니다, 감사합니다!

0개의 댓글