React : Hooks

김대은·2022년 7월 28일
0

useState

useState()는 함수형 컴포넌트 내부에서 state 값을 관리(변경 등)을 하기 위해 사용하는 Hook입니다.

const [ state,setState ] = useState(기본값);

구조 분해 할당을 통해 useState를 이용합니다.
보통 첫번째 배열 요소에 state 값을 넣고, 두번째 요소로 state 요소를 설정하는 함수를 넣어줍니다.
state설정 함수의 인자로 전달받은 값이 변경할 state값이 됩니다.

const onChange=()=>{
  setState(변경값)
  }

useEffect

https://velog.io/@dae_eun2/React-useEffect-%EB%A1%9C-%EB%9D%BC%EC%9D%B4%ED%94%84-%EC%82%AC%EC%9D%B4%ED%81%B4-%EB%8F%8C%EB%A6%AC%EA%B8%B0

이 글에 정리해 놨으나

 useEffect(() => {
  ~~~ 실행할 함수들~~~
  예를들어 여기서 setTimeout을 사용햇다면,
    return () => { // componentWillUnmount 
      //이곳에서 클리어 해줘야 한다.
      });
    };
  }, []); //빈 배열이면 ComponenetDidMount
  // 배열에 요소가 있으면, componentDidMount,componentDidUpdate

useRef

function TextInputWithFocusButton() {
  const inputEl = useRef(null);
  const onButtonClick = () => {
    // `current` points to the mounted text input element
    inputEl.current.focus();
  };
  return (
    <>
      <input ref={inputEl} type="text" />
      <button onClick={onButtonClick}>Focus the input</button>
    </>
  );
}

본질적으로 useRef는 .current 프로퍼티에 변경 가능한 값을 담고 있는 “상자”와 같습니다.
위와 같이 Dom에 접근하여 focus를 주는 방법도 있지만,
어떤 가변값을 유지하는데에 편리합니다.
useRef는 매번 렌더링을 할 때 동일한 ref 객체를 제공한다는 것입니다.
useRef는 내용이 변경될 때 그것을 알려주지는 않는다는 것을 유념하세요.
current 프로퍼티를 변형하는 것이 리렌더링을 발생시키지는 않습니다.

useContext + Context API

일반적인 React 애플리케이션에서 데이터는 위에서 아래로 (즉, 부모로부터 자식에게) props를 통해 전달되지만, 애플리케이션 안의 여러 컴포넌트들에 전해줘야 하는 props의 경우 (예를 들면 선호 로케일, UI 테마) 이 과정이 번거롭고, 에러를 유발 할 수 있습니다.

context를 이용하면, 트리 단계마다 명시적으로 props를 넘겨주지 않아도
많은 컴포넌트가 이러한 값을 공유하도록 할 수 있습니다.
ontext는 React 컴포넌트 트리 안에서 전역적(global)이라고 볼 수 있는 데이터를 공유할 수 있도록 고안된 방법입니다. 그러한 데이터로는 현재 로그인한 유저, 테마, 선호하는 언어 등이 있습니다

Context는 꼭 필 요할때만!

  • Context를 사용하면 컴포넌트를 재 사용하기 어려워질 수 있다.
  • Prop drilling 을 피하기위한 목적이라면,
    Component Composition(컴포넌트합성)을 먼저 고려해보자
    위의 예제는
    https://ko.reactjs.org/docs/context.html
    를 통해 확인 해볼수있다.

useContext

const value = useContext(MyContext);

context의 현재 값은 트리 안에서 이 Hook을 호출하는 컴포넌트에 가장 가까이에 있는 <MyContext.Provider>의 value prop에 의해 결정됩니다.

컴포넌트에서 가장 가까운 <MyContext.Provider>가 갱신되면 이 Hook은 그 MyContext provider에게 전달된 가장 최신의 context value를 사용하여 렌더러를 트리거 합니다.
즉, 상위컴포넌트에서 React.Memo를 사용해도, useContext를 사용 하고 있는
컴포넌트 자체에서부터 재 랜더링 됩니다.

useContext를 호출한 컴포넌트는 context 값이 변경되면 항상 리렌더링 될 것입니다.
컴포넌트를 리렌더링 하는 것에 비용이 많이 든다면, 메모이제이션을 사용하여 최적화할 수 있습니다.

function Button() {
  let appContextValue = useContext(AppContext);
  let theme = appContextValue.theme; // Your "selector"

  return useMemo(() => {
    // The rest of your rendering logic
    return <ExpensiveTree className={theme} />;
  }, [theme])
}
 - - - - - -
 function Button() {
  let appContextValue = useContext(AppContext);
  let theme = appContextValue.theme; // Your "selector"
  return <ThemedButton theme={theme} />
}

const ThemedButton = memo(({ theme }) => {
  // The rest of your rendering logic
  return <ExpensiveTree className={theme} />;
});

context 사용예제

const themes = {
  light: {
    foreground: "#000000",
    background: "#eeeeee"
  },
  dark: {
    foreground: "#ffffff",
    background: "#222222"
  }
};

const ThemeContext = React.createContext(themes.light);

function App() {
  return (
    <ThemeContext.Provider value={themes.dark}>
      <Toolbar />
    </ThemeContext.Provider>
  );
}

function Toolbar(props) {
  return (
    <div>
      <ThemedButton />
    </div>
  );
}

function ThemedButton() {
  const theme = useContext(ThemeContext);
  return (
    <button style={{ background: theme.background, color: theme.foreground }}>
      I am styled by theme context!
    </button>
  );
}

useReducer

다수의 하윗값을 포함하는 복잡한 정적 로직을 만드는 경우나 다음 state가 이전 state에 의존적인 경우에 보통 useState보다 useReducer를 선호합니다.
또한 useReducer는 자세한 업데이트를 트리거 하는 컴포넌트의 성능을 최적화할 수 있게 하는데,
이것은 콜백 대신 dispatch를 전달 할 수 있기 때문입니다.

const initialState = {count: 0};

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return {count: state.count + 1};
    case 'decrement':
      return {count: state.count - 1};
    default:
      throw new Error();
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <>
      Count: {state.count}
      <button onClick={() => dispatch({type: 'decrement'})}>-</button>
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
    </>
  );
}

useCallback

const memoizedCallback = useCallback(
  () => {
    doSomething(a, b);
  },
  [a, b],
);

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

deps의 state가 변경 되기전까지 안에 함수를 저장해둡니다.

useCallback(fn, deps)은 useMemo(() => fn, deps)와 같습니다.

profile
매일 1% 이상 씩 성장하기

0개의 댓글