Custom Hooks 만들기

seul_velog·2022년 4월 8일
0

React

목록 보기
8/11
post-thumbnail
post-custom-banner

Custom Hooks

컴포넌트를 만들면 반복되는 로직이 자주 발생하게 된다. 이때 커스텀 Hooks 를 만들어서 반복되는 로직을 정의한 후 간편하게 호출함으로써 쉽게 재사용할 수 있다.

  • 주로 use 라는 키워드로 시작하는 파일을 만들고 안에 함수를 작성해서 사용한다.

  • useState , useEffect , useReducer , useCallback 등 Hooks를 사용해서 원하는 기능을 구현하고 컴포넌트에서 사용하고 싶은 값들을 반환해주면 된다.

  • 변경사항이 있을 씨 커스텀 훅에서만 변경하면 되므로 수정하기에 효율적이다.

  • 커스텀 훅을 작성할 때는 항상 use로 시작한다.

📌 Hook의 특징
훅 또는 함수 컴포넌트 안에서만 실행이 가능하다. 즉 훅 안에 다른 훅을 사용할 수 있다.



커스텀 훅 만들어보기

✍️ 여러개의 Input 관리하기

기본적인 입력 폼

import React, { useState, useCallback } from 'react';

// state
const [text, setText] = useState({
  id: '',
  pw: '',
});

// func
const onChange = useCallback(
  (e) => {
    const { value, name } = e.target;
    setText({ ...text, [name]: value });
  },
  [text]
);

return (
  <>
    <input id='id' value={text.id} onChange={onChange} />
    <input id='pw' value={text.pw} onChange={onChange} />
  </>
);
  • 위와 같은 기본적인 입력폼 코드는 여러 군데에서 자주 사용될 수 있다. 그때마다 모든 컴포넌트에 해당 로직을 넣는다면 비효율적일 수 있는데, 이때 커스텀 훅을 만들어서 재사용할 수 있다. 😀

✍️ 훅 반영하기

import { useState, useCallback } from 'react';

export default (initalValue = null) => {
  // state
  const [data, setData] = useState(initalValue);

  // func
  const handler = useCallback(
    (e) => {
      const { value, name } = e.target;
      setData({
        ...data,
        [name]: value,
      });
    },
    [data]
  );
  return [data, handler];
};
// 반영한 로직
import UseInput from './UseInput';

const [text, setText] = useInput({
  id: '',
  pw: '',
});

return (
  <>
    <input id='id' value={text.id} onChange={onChange} />
    <input id='pw' value={text.pw} onChange={onChange} />
  </>
);
  • useInput 훅 안에 useState와 useCallback에 있는 함수를 미리 정의했으므로 컴포넌트에서는 훅을 사용하기만 하면 된다.
  • 커스텀 훅을 다른 컴포넌트에서도 재활용 할 수 있게 됨으로써 동일한 로직을 수행하는 컴포넌트가 많을 경우 커스텀 훅을 유용하게 사용할 수 있다.



✍️ useFetch 만들어서 사용하기

// useFetch.tsx
import {useEffect, useState} from 'react';
import {getToken} from 'AuthContext';

const useFetch = (url: string) => {
  const [fetchData, setFetchData] = useState({});

  useEffect(() => {
    if (!url) {
      return;
    }
    const getFatchData = async (url: string) => {
      const token = await getToken();
      const getData = await fetch(url, {
        method: 'GET',
        headers: {
          Authorization: token,
        },
      });
      const res = await getData.json();
      setFetchData(res);
    };

    getFatchData(url);
  }, [url]);

  return fetchData;
};

export default useFetch;


// AuthContext.tsx의 getToken
export const getToken = async () => {
  try {
    const token = await AsyncStorage.getItem('access_token');
    return String(token);
  } catch (error) {
    throw new Error('token 저장 실패');
  }
};
  • token을 사용해서 data를 받아오는 로직을 재사용하기 위해서 useFetch 훅을 만들었다.

✍️ 훅 반영하기 (react-native)

// config.ts
export const BASE_URL = '...';
const API = {
  departmentList: `${BASE_URL}/appointments/departments`,
  ...
};
export default API;


// MainHome
import useFetch from 'components/useFetch';

const MainHome = ({navigation}: MainHomeScreenProps) => {
  const departmentListUrl = `${API.departmentList}`;
  const departmentListData = useFetch(departmentListUrl).result;

  return (

    ...

      <View>
        <FlatList
          data={departmentListData} // 받아온 데이터를 넣어준다.
          columnWrapperStyle={{
            justifyContent: 'space-between',
            marginBottom: 55,
          }}
          renderItem={({item}) => (
            <Pressable
              style={[
                styles.alignStyle,
                styles.iconBox,
                {width: width / 5, height: width / 5},
              ]}
              onPress={() => {
                navigation.navigate('DocList', item);
              }}>
              <Image
                source={{
                  uri: item.thumbnails,
                }}
                style={styles.iconImg}
              />
              <Text style={[styles.iconTitle, styles.nameText]}>
                {item.name.replace(' ', `${'\n'}`)}
              </Text>
            </Pressable>
          )}
          keyExtractor={item => item.id.toString()}
          numColumns={3}
        />

   ...

  );
};




reference)
customHooks

profile
기억보단 기록을 ✨
post-custom-banner

0개의 댓글