what is custom hook and how to use it (2)

hyeok·2023년 1월 7일
0

A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures#lexical_scoping

By closure we can use variable value even though the variable is in outside of lexical scope. Lexical scope is that the way of parser understand the variable.

For example, let me show the useState imitation.

function useState(initialValue) {
  var _val = initialValue 
  function state() {
    return _val 
  }
  function setState(newVal) {
    _val = newVal
  }
  return [state, setState]
}
var [foo, setFoo] = useState(0) 
console.log(foo()) // 0 
setFoo(1) 
console.log(foo()) // 1 

reference : https://hewonjeong.github.io/deep-dive-how-do-react-hooks-really-work-ko/

When we call setFoo(1), _val is in outside of lexicalcope. However, we can access to the _val and change it. In this way we can manage the state in the react.

We can use this hook for making isolated state from main logic and modify it and use it. I will show the example in the next blog.

Custom hook have useXXX as prefix. This prefix let react app knows that the function is custom hook. It has some grammer that we should follow. One of main grammers is that custom hook should be called in component level. But we can use custom hook in the custom hook. So i made a custom hook for api handling.

import { useCallback } from "react"
import axios from "axios"
import { urlTypes } from "./configs/urlTypes";
import { urls } from "./configs/urls";
import { useDispatch } from 'react-redux'
import { showAlertModal } from "@/modules/alertModalReducer";
import service from '@/modules/Common/service'
import { useCookies } from "react-cookie";

interface configsInterface {
     method: string
     params?: any
     headers?: {
          Authorization: string
     }
}

const useApiHandling = <T = any>({
     urlType,
     method = 'get',
     needAuthority = true
}: {
     urlType: urlTypes,
     method?: string,
     needAuthority?: boolean,
}) => {
     const [cookies, ,] = useCookies(["loginToken", "loginStatus", "companySeq"]);
     const dispatch = useDispatch()

     const getConfigs = useCallback((params: any = {}) => {
          const configs: configsInterface = {
               method,
               params,
          }
          if (needAuthority) {
               const { loginToken } = cookies
               configs["headers"] = { Authorization: `Bearer ${loginToken}` }
          }
          return configs
     }, [method, needAuthority, cookies])

     const checkValid = (result: any) => {
          const validChecker = result?.data?.result
          if (typeof validChecker === "boolean" && validChecker === false) {
               const message = service.getValue(result, "data.message", "error message")
               dispatch(showAlertModal(message, "", "확인"));
               return false
          }
          return true
     }

     const doRequest = useCallback(async (params: any = {}) => {
          try {
               const url = urls[urlType]
               if (url) {
                    const fetchUrl = process.env.REACT_APP_API_HOST + url
                    const configs = getConfigs(params)
                    const result = await axios(fetchUrl, configs)
                    const isValid = checkValid(result)
                    if (!isValid) {
                         return null
                    } else {
                         return result
                    }
               }
               return null
          }
          catch (error) {
               dispatch(showAlertModal('error', '', 'confirm'));
               return null
          }

     }, [urlType, method]);


     return { doRequest }
};
export default useApiHandling

By this hook i can reduce the code when i use restfull api. First of all i can reduce error handling cod. I used the try, catch when i call axios and i make a error modal when there is a error. Also it shows error message, if the server sends error message.
Second I can reduce config code, like cookie or params. It is annoying that always call cookie and put in the header when we use api. I reduced it by this hook.
Third I can reduce handling of api endpoint code. I can get the endpoint url string by the url type. When i want to call the api, i just use the type, not write down a string. See the below code.

const { doRequest: getEvaluationYearData } = useApiHandling({ urlType: urlTypes.GET_EVALUATION_YEAR_DATA_LIST })

Actually this api handling hook can be used in just a simple function but we can not use useCookie in the simple function.
So i made a customfunction for using useCookie.

I will show the other example of custom hook in the next blog.

profile
내가 만든 소프트웨어가 사람들을 즐겁게 할 수 있기 바라는 개발자

0개의 댓글