React - FunctionalComponent. Hook?
Hook은 리엑트 v16.8에 추가된 기능이며, 함수형 컴포넌트에서 state와 생명주기와 같은 여러 기능을 제공하는 라이브러리 입니다.
- 최상위(at the Top Level)에서만 hook을 호출해야합니다.
반복문, 조건문 또는 중첩된 함수 내에서 hook을 호출하면 안됩니다.
early return(함수 또는 반복문 등에서 끝에서 return 되기 전 if문 안에서 일찍 return 하는 것)전에 항상 React함수의 최상위에 hook을 호출해야합니다. - 오직 React 함수 내에서 hook을 호출해야 합니다.
import React, { useState } from "react"
function HookTest(props) {
if (props.name == 'User') {
const [name, setName] = useState('User'); // 오류: Hook 규칙 위반
}
}
1. React Hook 내장 API
1. useState : 컴포넌트의 state(상태)를 관리합니다.
(클래스형 컴포넌트의 constructor()에서 state를 초기화하는 것과 비슷한 역할)
// useState의 사용 구조
const [사용할 state, state의 상태값을 설정하는 함수] = useState(state 초기값)
// 일반적인 useState의 사용
const [name, setName] = useState('User');
setName('UserChange'); //name을 UserChange로 바꿔줌.
// 여러개의 state를 한번에 관리하고자 할때 => prevState를 통해 관리
const [userInfo,setUserInfo] = useState({name:'User', email:'a@tistory.com', age:'28' });
setUserInfo(prevState=> {
return {...prevState, name:'UserChange'}
}) //prevState에 userInfo 값들이 들어있고, 이를 통해 바꾸고자하는 name값만 UserChange로 바꿔줌.
2. useEffect : state값이 변경 될 때마다, 특정 기능이 동작하도록 관리합니다.
(클래스형 컴포넌트의 componentDidMount(), componentDidUpdate, componentWillUnmount() 것과 비슷한 역할)
// useEffect의 사용 구조 => []배열에 넣어준 state가 바뀔 때 마다 동작.
useEffect(() => {
~ 함수 로직 전개 ~
}, [state값])
// 1. 빈 배열은 구성 요소가 마운트 될 때마다 효과가 한 번만 실행되고 모든 다시 렌더링시 실행되지 않음을 의미
// componentdidMount
useEffect(() => {
console.log('componentdidMount')
}, [])
// 2. 배열에 state값을 넣어주면 넣어준 state가 변화되면 실행
// componentdidUpdate
useEffect(() => {
console.log('name Changed')
}, [name])
3. useContext : 여러개의 컴포넌트에서 사용 가능한, 변수 나 함수를 만들 수 있습니다.
(전역적 성질, 2중 3중으로 prop를 내려 주는 행위를 방지할 수 있음.)
// newContext.js
import { createContext } from "react" // createContext 함수 불러오기
// context안에 homeText란 변수를 만들고, 공백("") 문자를 저장한다.
const newContext = createContext({
homeText: "",
})
// Home.js
import React from "react";
import { Text, View } from "react-native";
import { useContext } from "react";
import { newContext } from "../newContext"; //newContext.js의 newContext를 불러옴
export default function Home() {
// useContext hook 사용해서, newContext에 저장된 정보 가져오기
const { homeText } = useContext(newContext);
// 불러온 정보 사용하기!!
return (
<View>
<Text>{homeText}<Text>
</View>
);
}
4. useReducer : useState()의 대체 함수로, 다양한 컴포넌트 상황에 따라 상태 값을 설정합니다.
const [state, dispatch] = useReducer(reducer, initialState, init);
// 첫 번째 인자로 현재 상태(state)와 행동(action)을 인자로 받는 reducer 함수를,
// 두 번째 인자로 상태의 초기값을
// 세 번째 인자로는 상태 초기화 함수를 넣고 현재 상태(state)와 액션을 발생시키는 함수(dispatch)를 반환
5.useCallback, useMemo
5-1. useCallback()
렌더링 최적화에 사용하며, 의존 배열에 있는 값이 변할 때만 첫 번째 인자로 주어진 콜백함수를 새로 생성하여 반환합니다.
const memoizedCallback = useCallback(callback, dependency);
// 두 번째 인자로 주어진 의존 배열(dependency)의 값이 바뀌면
// 첫 번째 인자로 주어진 콜백함수(callback)를 새로 생성하여 반환
// ex) number의 값이 변할 때마다 number의 값에 1을 더해주는 함수를 기억하고있다가 클릭 이벤트가 발생할 경우 해당 함수를 실행
const onClick = useCallback(e => { e.preventDefault(); setNumber(number + 1); ), [number]};
5-2. useMemo()
연산 최적화에 사용하며, 의존 배열에 있는 값이 변할 때만 첫 번째 인자로 주어진 콜백함수를 실행하여 구한 값을 반환합니다.
const memoizedValue = useMemo(callback, dependency);
// 렌더링 과정에서 두 번째 인자로 받은 의존 배열(dependency)내 값이 바뀌는 경우에만
// 첫 번째 인자로 받은 콜백함수를 실행하여 구한 값을 반환하는 함수
// ex) 배열의 모든 요소 합을 구하는 함수
const getSum = (arr) => { return arr.reduce((a, b) => a + b); }
const arr = [1, 2, 3, 4];
const sum = useMemo(() => getSum(arr), [arr]);
=> useMemo()는 숫자 또는 문자열, 배열, 객체 등의 값을 반환하고 useCallback()은 함수를 반환한다는 점에서 차이가 있습니다.
6.useRef, useImperativeHandle
6-1. useRef()
ref를 쉽게 사용할 수 있도록 해주고, 컴포넌트나 Html 요소를 래퍼런스로 관리 가능합니다.
6-2. useImperativeHandle()
useRef로 만든 래퍼런스를 상위 컴포넌트로 전달할 수 있습니다. (상위 컴포넌트에서 하위 컴포넌트의 함수, 데이터 가져오기 가능)
// container.js
const MainContainer = (props) => {
const mainContent = useRef();
return (
<div>
<MainContent
ref={mainContent}
/>
</div>
)
};
// ref를 연결하면 하위 컴포넌트 MainContent에 접근이 가능
// mainContent.current.name
// mainContent.current.funcTest
// MainContent.js
// ref를 forwardRef 내부의 (props, ref) => ... 함수의 두 번째 인자로 전달
const MainContent = forwardRef((props, ref) => {
const [name, setName] = useState('User');
let funcTest = () => {
console.log('ref');
}
useImperativeHandle(ref, () => ({ //forwardRef와 같이 써야함.
name: name,
funcTest:funcTest
}));
});
useState, useEffect, useRef, useImperativeHandle 는 프로젝트에 직접 사용을 해보았고
useContext, useReducer, useCallback, useMemo 는 아직 사용을 못해보았다.
사용하지 못한 hook 내장 API도 기회가 될 때 사용해보고 다시 정리해둬야겠다!
*참조
https://talking-potato.me/m/52
[React] 리액트 훅 💪
오늘을 리액트 훅에 대해 다루겠습니다. 리액트 훅(React Hooks)이란 리액트 16.8 버전부터 추가된 기능으로, 클래스 컴포넌트와 생명주기 메서드를 이용하여 작업을 하던 기존 방식에서 벗어나 함
talking-potato.me