TypeScript로 사용자 정의 HTTP 후크 만들기

5397 단어
이 기사에서는 React 또는 React Native 앱에서 HTTP 호출을 수행하기 위해 사용하기 쉬운 HTTP 후크를 만드는 방법을 찾을 수 있습니다.

먼저 간단한 후크를 만들어 보겠습니다.

export function useHttp<T>() {}


  • T는 후크 및 HTTP 응답이 반환할 데이터 유형입니다
  • .

    몇 가지 매개변수를 추가해 보겠습니다.

    export function useHttp<T>(
      request: HttpRequest<T>,
      cb?: HttpCallback<T>,
      config?: HttpConfig<T>,
    ): HttpHook<T> {}
    

  • 요청: request: HttpRequest<T>

  • type HttpRequest<T> = (body?: any) => Promise<T>
    

    HttpRequest는 후크가 실행할 실제 API 호출이어야 합니다. body 객체는 요청할 때마다 전달할 데이터입니다.

    프라미스 대신 URL을 전달하면 간단할 수 있지만 동시에 여러 API를 호출하려면 어떻게 해야 할까요?
  • 콜백:
    cb?: HttpCallback<T>


  • type HttpCallback<T> = (data: T, error?: HttpError) => void
    

    API 호출이 해결될 때마다 호출될 콜백 함수입니다.
  • 구성: config?: HttpConfig<T>

  • type HttpConfig<T> = {
      headers: any,
      timeout: number
    }
    

    여기에서 API 호출에 원하는 사용자 지정 구성을 추가하거나 후크의 동작을 변경하는 항목을 추가할 수 있습니다.
  • 반환 유형

  • type HttpHook<T> = [(body?: any) => Promise<void>, {
      loading: boolean, 
      data: T, 
      error: HttpError | null
    }]
    

    후크는 2개의 값을 반환합니다.
  • 실제 HTTP 요청
  • 로드 상태, 오류 상태 및 응답 데이터가 있는 개체

  • 오류 유형은 API가 반환하는 모든 것일 수 있습니다. 예:

    export class HttpError {
      status: number
      message: string
    
      constructor(status: number, message: string) {
        this.status = status
        this.message = message
      }
    }
    

    이제 후크의 실제 논리를 살펴보겠습니다.

    // Create some states for our 
    const [loading, setLoading] = useState<boolean>(false)
    const [error, setError] = useState<HttpError | null>(null)
    
    async function fetchApi(body?: any): Promise<void> {
      setLoading(true)
      let err = null
      let data: T = {} as T
      try {
        // Await for the request
        const response: any = await request(body)
        // This might vary based on your API
        if(response.data) {
          data = response.data;
        } else {
          data = response;
        }
      } catch (_err) {
        err = _err
      } finally {
        // Set loading to false and verify the response status, if there's an error or whatever you need
        setLoading(false)
        if (err) {
          if(cb) cb(data, err)
          setError(err)
        } else {
          setResponse(data)
          setError(null)
          if(cb) cb(data)
        }
      }
    }
    
    return [fetchApi, {loading, data: response, error}]
    

    이것은 후크에 대한 가장 간단한 논리입니다. 여기에서 고유한 구성 매개변수를 추가하고, API를 기반으로 유효성 검사를 변경할 수 있으며, 여러 API를 사용해야 하는 경우 dataExtractor 함수를 만들 수도 있습니다.

    지금! 몇 가지 예를 들어 보겠습니다.

    먼저 데이터 유형과 더미 API 호출을 생성합니다.

    type LightsaberType = {
      color: string,
      material: string
    }
    
    let lightsabers: LightsaberType[] = [{
      color: 'blue',
      material: 'Electrum Plated'
    }, {
      color: 'red',
      material: 'Durasteel'
    }]
    
    const fetchLightsaberList = async () => {
      return lightsabers
    }
    

    그리고 이렇게 간단합니다

    export const LightsaberListScreen = () => {
      const [getLightsabers, { loading, data }] = useHttp<LightsaberType[]>(fetchLightsaberList)
    
      useEffect(() => {
        getLightsabers()
      }, [])
    
      return (
        <View>
          {loading? (
            <ActivityIndicator />
          ) : (
            <FlatList
              data={data || []}
              renderItem={({item}) => null}
            />
          )}
        </View>
      )
    }
    
    

    그러나 자신의 상태를 처리하려면 어떻게해야합니까?

    export const LightsaberListScreen = () => {
      const [lightsabers, setLightsabers] = useState<LightsaberType[]>([])
      const [getLightsabers, { loading }] = useHttp<LightsaberType[]>(
        fetchLightsaberList,
        (data, err) => {
          if(err) showCustomToast('Oh no, I don\'t have any lightsaber!')
          setLightsabers(data)
        }
      )
    
      useEffect(() => {
        getLightsabers()
      }, [])
    
      return (
        <View>
          {loading? (
            <ActivityIndicator />
          ) : (
            <FlatList
              data={lightsabers}
              renderItem={({item}) => null}
            />
          )}
        </View>
      )
    }
    
    

    또는 당신은 시체를 통과해야합니다

    const postLightsaber = async (lightsaber: LightsaberType) => {
      lightsabers.push(lightsaber)
      return lightsabers
    }
    
    
    ...LightsaberListScreen component
    const [createLightsaber] = useHttp<LightsaberType[]>(
        (body: LightsaberType) => postLightsaber(body),
        (data, err) => {
          if(err) showCustomToast('Oh no, you\'ll need to go back to Ilum')
          setLightsabers(data)
        }
      )
    
    return (
      <Button 
        text="Create your own lightsaber"
        onPress={() =>  createLightsaber({
            color: 'cian',
            material:'Aurodium'
      })}/>
    )
    
    

    이것은 내 첫 번째 기사이므로 정말 당신이 그것을 좋아하고 나는 제안에 완전히 열려 있습니다!

    즐거운 코딩 🚀

    좋은 웹페이지 즐겨찾기