React & React-hooks 간단정리

박동건·2020년 8월 23일
0

TIL(2020)

목록 보기
44/49

리액트를 정리하고자 유튜브에 Codevolution 채널(https://www.youtube.com/channel/UC80PWRj_ZU8Zu0HSMNVwKWw)에서 ReactJS Toturial을 학습했다.

이번 포스팅은 아는 내용들은 빠르게 넘어갔고, 중요하다 싶은 내용이나 가물가물하던 내용들을 내가 이해한 바를 기록하는 용도이다. 따라서, 설명,예제 등 생략된 부분이 많다.

1. Props

파라미터로 props를 넘기면 해당 컴포넌트의 attribute가 Object형태로 넘어간다.

// App.js
<Hello name="Bruce" heroName="Batman" />
// Hello.js
const Hello = (props) => {
  console.log(props);  
  return (
    <>
      <p>
    	// 프로퍼티의 값을 가져올 수 있음.
        Hello, {props.name} aka {props.heroName}
      </p>
    </>
  );
};
// console.log
{name: "Bruce", heroName: "Batman"}

2. state

동적인 데이터를 다룰 때 쓴다. setState()를 통해 비동기적으로 함수를 호출하는데 이것이 호출되면 render()가 호출됨. => view가 계속 업데이트된다는 것.

  • props는 read-only이고, 부모로 부터 설정되거나, 기본값으로만 한번 설정된다.
  • state는 change가능하고, component에서 처음 init을 해야만 설정된다.
const Counter = ({count}) => {
  return (
    <>
      <p>{count}</p>
    </>
  );
};

3. handling

  • 컴포넌트는 하나의 wrap으로 감싸져있어야한다. (나는 <> </> 주로 사용한다)
  • state에서 함수를 실행하면 안된다.
// 버튼을 클릭하지도 않았는데 이미 실행되어버린다. 이후에 버튼을 클릭 해도 실행 안된다.
<button onClick={clickHandler()}>Click</button>  X
      
<button onClick={clickHandler}>Click</button>    O

4. Conditional Rendering

  • if구문 인라인으로 표현하기 (true && expression)
 {unreadMessages.length > 0 &&
        <h2>
          You have {unreadMessages.length} unread messages.
        </h2>
      }
  • if-else 구문 인라인으로 표현하기 (condition ? true: false)
    <div>
      The user is <b>{isLoggedIn ? 'currently' : 'not'}</b> logged in.
    </div>
  • 반복 되는 것은 map메서드 사용하기

5. useState

import React, { useState } from "react";

const Whoru = () => {
  const [name, setName] = useState({ firstName: "", lastName: "" });
  return (
    <>
      <input
        type="text"
        value={name.firstName}
	//setName할때, 업데이트 외에 부분은 ...연산자로 초기화 되지 않게 한다.
        onChange={(e) => setName({ ...name, firstName: e.target.value })}
      />
      <input
        type="text"
        value={name.lastName}
        onChange={(e) => setName({ ...name, lastName: e.target.value })}
      />
      <h2> Your firstName is : {name.firstName}</h2>
      <h2> Your lastName is : {name.lastName}</h2>
    </>
  );
};

export default Whoru;

A component is changing an uncontrolled input of type text to be controlled error in ReactJS : https://stackoverflow.com/questions/47012169/a-component-is-changing-an-uncontrolled-input-of-type-text-to-be-controlled-erro

6. useEffect

useEffect(() => {
    effect
    return () => {
      cleanup
    }
  }, [input])
  • input이라고 적힌 두번째 인자의 배열에 들어가는 value가 변하지 않으면 이펙트가 실행되지 않음!
  • Run effects only once => 두번째 인자의 배열을 빈 배열로!
  • cleanup => effect는 한번이 아니라 렌더링이 실행되는 때마다 실행된다.
    리액트가 다음 차례의 effect를 실행하기 전에 이전의 렌더링에서 파생된 effect 또한 정리하는 이유가 바로 이 때문임.

7. useContext

여러개의 컴포넌트를 거쳐서 props, state 를 전달할 때 유용하다.

provider가 store라 생각하자.

시각적으로 잘 보여준다.
(https://xiubindev.tistory.com/105)
코드적으로 흐름을 살피기에 좋다.
(https://sg-choi.tistory.com/240)

// context 생성
import React , {createContext, useContext} from 'react';

export const NameContext = createContext();
// Provider 컴포넌트로 랜더링 할 컴포넌트를 감싸준다.
// 넘겨줄 값을 value에 넣는다. 
<NameContext.Provider value="ape">
  <Human />
</NameContext.Provider>

// 전달 하고자 하는 컴포넌트에서 useContext로 조회한다.
const Name = useContext(NameContext)
return (
  <div> 
    <p>Hello, {name}</p>
  </div>
)

8. useReducer

1. useReducer(reducer, initialState)
2. define the initial state and reducer function
const initialState = {
  firstCounter: 0,
  secondCounter : 10
};

const reducer = (state, action) => {
  switch(action.type) {
    case 'increment' : 
      return { ...state, firstCounter : state.firstCounter + action.value}
    case 'decrement' :
      return { ...state, firstCounter : state.firstCounter - action.value}
    case 'increment2' :
      return { ...state, secondCounter : state.secondCounter + action.value}
    case 'decrement2' :
      return { ...state, secondCounter : state.secondCounter - action.value}
    case 'reset' : 
      return initialState
    default:
      return state
  }
}
3. dispatch
function Counter() {
  const [count, dispatch] = useReducer(reducer, initialState)
  
  return (
    <div>
      <div>1st Count : {count.firstCouner}</div>
      <div>2nd Count : {count.secondCounter}</div>

      <button onClick={() => dispatch({type:'increment', value : 1})}>Increment 1</button>
      <button onClick={() => dispatch({type:'decrement', value : 1})}>Decrement 1</button>

      <button onClick={() => dispatch({type:'increment', value : 5})}>Increment 5</button>
      <button onClick={() => dispatch({type:'decrement', value : 5})}>Decrement 5</button>

      <button onClick={() => dispatch({type:'reset'})}>Reset</button>

      <button onClick={() => dispatch({type:'increment2', value : 1})}>Increment 1</button>
      <button onClick={() => dispatch({type:'decrement2', value : 1})}>Decrement 1</button>
    </div>
  )
}

9. Optimization

useCallbackuseMemo를 제대로 사용 하는 법 :
(https://atercatus.github.io/react/2020-01-07-useMemo-useCallback)
useMemo는 큰 데이터 처리에 사용해야하며, useCallback은 쓸모없는 렌더링을 피하기 위해 코드에 더 많은 종속성을 추가하는 방법이다.
(https://blog.hackages.io/react-hooks-usecallback-and-usememo-8d5bb2b67231)

연관있는 컴포넌트가 값이 바뀔 때 전부 리랜더가 된다. -> 퍼포먼스 이슈가 생긴다.

React.memo

Component를 React.memo로 감싸주면 컴포넌트에서 리렌더링이 필요한 상황에서만 리렌더링을 하도록해 준다.


export default React.memo(component);

useCallback

React에서 컴포넌트가 다시 렌더링 될 때에는 컴포넌트 안에 선언된 함수들을 새로 생성한다.
그래서 계속 렌더링 되면 함수도 계속해서 새로 생성된다는 것.

  • 컴포넌트에 작성하는 함수들은 useCallback으로 감싸야 한다.
  • 자식컴포넌트에 함수를 props로 내릴때는 useCallback을 반드시 사용(자식 리렌더링 방지)
  • 함수를 기억한다. (두번째 인수로 전달된 의존성이 변경되기 전까지)
const memoizedCallback = useCallback(
  () => {
    doSomething(a, b);
  },
  [a, b],
);

메모이제이션된 콜백을 반환합니다.

useMemo

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

메모이제이션된 값을 반환합니다.

10. useRef

특정 Dom을 선택해야 하는 상황에 사용.

import React, { useEffect, useRef } from "react";

function Focus() {
  const inputRef = useRef(null);

  useEffect(() => {
    // focus the input el
    inputRef.current.focus();
  }, []);

  return (
    <div>
      <input ref={inputRef} type="text" />
    </div>
  );
}

export default Focus;

hooks로 useContext와 useReducer를 공부하면서 어려웠던 Redux가 어느정도 가닥이 잡힌다. 😛😛

다시금 느끼는 거지만 역시 공식 레퍼런스 만한게 없다.
(https://ko.reactjs.org/docs/hooks-reference.html)

profile
박레고의 개발 블로그

0개의 댓글