React hooks - useLayoutEffect, useRef, useContext

nearworld·2022년 7월 23일
0

React Hooks

목록 보기
3/6

useLayoutEffect 예제

useLayoutEffect동기적으로 작동하며 render후에 실행된다.
useEffect와 다른 부분이 이 부분이다.
useEffectrender -> paint -> useEffect.
useLayoutEffectrender -> useLayoutEffect -> paint.
paint 되기전에 실행되므로 useLayoutEffect에 의해 상태가 바뀌면 그 다음 단계인 paint로 가지 않고 render가 실행되므로 화면이 깜박거림을 방지할 수 있다.
paint단계는 웹페이지에 컴포넌트를 나타내는 단계이므로 상태가 변경된 컴포넌트에 다시 paint되어 깜박거림을 일으킨다.

const [value, setValue] = useEffect(0);

useLayoutEffect(() => {
  if (value === 0)
    setValue(10)
  })

위 코드에서 상태 변수value의 값이 0이므로 render -> useLayoutEffect 단계에서 setValue(10)이 호출되어 상태 변경으로 인해 render가 다시 실행된다. 이 말은 paint가 되지 않았으므로 다시 render후에 paint가 되는 것이므로 화면 깜박거림이 나타나지 않는다.

공부하면서 알게된 것은 useLayoutEffect를 지양하고 useEffect를 주로 써야한다는 것이다. 이유는 useLayoutEffect동기적으로 작동하므로 paint 이전에 useLayoutEffect에서 복잡한 로직이 처리되는 것이라면 유저들은 웹페이지가 바로 화면에 나타나는 것을 보지 못하는 좋지 않은 유저 경험을 하게 되기 때문인듯하다.

요약

  1. synchronous
  2. render -> useLayoutEffect -> paint

useRef 예제

const inputEl = useRef(null)

const handleClick = () => {
  // button이 클릭되면 `input`요소에 focus 두기.
  inputEl.current.focus();
}

return(
  <input ref={inputEl} type='text'/>
  <button onClick={handleClick}>검색</button>
)

요약

  1. .current 프로퍼티를 가진 오브젝트를 리턴
  2. HTML 요소에 직접적으로 접근
  3. event 발생없이 HTML 요소에 접근 가능

만약, useRef가 없다면 event가 일어날때만 onClick과 같은 어트리뷰트를 등록하여 event.target으로 접근해야할 거 같다.

useContext 예제

상태 변수를 글로벌로 설정하면 자식 컴포넌트들을 통해 계속 props를 던져주면 Props drilling 이슈를 피할 수 있다.

먼저 CardContext 를 생성하기 위한 코드를 작성한다.

CardContext.tsx

// CardContext.tsx
type CardContextProps {
	cards: number,
	setCards: React.Dispatch<React.SetStateAction<number>>
}
export const CardContext = createContext<CardContextProps | null>(null);

그런 다음, 다른 자식 컴포넌트들을 모두 포함할 App.tsx.Provider 컴포넌트를 추가하여 자식 컴포넌트들을 감싼다. 그러면, 자식 컴포넌트들은 .Provider 컴포넌트의 value프로퍼티에 담긴 데이터에 접근할 수 있게 된다.

App.tsx

// App.tsx
function App() {
	const [cards, setCards] = useState(10);
	return (
  		<CardContext.Provider value={{cards, setCards}}>
    		<Home />
  		</CardContext.Provider>
	);
}

자식 컴포넌트 중 하나인 Home컴포넌트에서 이제 cards, setCards에 접근할 수 있다.
방법은 Home 컴포넌트에서 useContext를 써서 CardContext에 접근하면 cards, setCards에 접근할 수 있다.

Home.tsx

// Home.tsx
import CardContext from './CardContext';

function Home() {
  const cardContext = useContext(CardContext);
	return (
    <div>
      카드: {cardContext.cards}</div>
  )
}

cardContext가 `{cards, setCards}를 받았으므로 Context API를 사용하여 글로벌 상태 변수를 사용하는데 성공했다.

위 방식으로 개발중인 포트폴리오에 적용한

결과물

profile
깃허브: https://github.com/nearworld

0개의 댓글