향상된 React 코드 – 맞춤형 연결

나와 다른 많은 사람들이 반응하는 주요 원인 중 하나는 우리가 다시 사용할 수 있는 부분으로 표시할 수 있도록 하는 것이다.
사용자 정의 React 갈고리는 응용 프로그램 상태에 대해 같은 작업을 수행할 수 있도록 합니다.
나는 맞춤형 갈고리의 이름이 그것들을 실제보다 더 복잡하게 보일 것이라고 생각한다.사용자 정의 갈고리는 React 라이브러리의 특정 함수를 호출하는 함수일 뿐입니다.
그것들은 함수일 뿐이기 때문에, 함수가 할 수 있는 모든 일을 할 수 있다.응용 프로그램에서 관심의 분리를 유지하고 깨끗하고 유지보수가 가능하며 읽기 쉬운 코드를 만드는 데 도움을 줄 수 있습니다.
예를 하나 봅시다.

하나의 예


React 애플리케이션은 일반적으로 비동기식 작업을 수행해야 합니다.PDF를 생성하여 iframe에 표시해야 한다고 가정합니다.PDF를 생성하는 데 몇 초가 걸릴 수 있으므로 프로세스를 시작한 다음 런타임 시 로드 표시기를 표시하고 완료 후에 PDF 또는 오류 메시지를 표시해야 할 수 있습니다.첫 번째 시도는 다음과 같습니다.
const generatePDF = (contents) => {
  // Generate PDF
  ...
  // Returns a promise
}

const PDF = ({ pdfContents }) => {
  const [{ status, data: pdf, error }, setState] = React.useReducer(
    (prevState, newState) => ({ ...prevState, ...newState }),
    { status: 'idle', data: null, error: null }
  )

  React.useEffect(() => {
    setState({ status: 'pending' })
    generatePDF(pdfContents).then(
      (data) => setState({ data, status: 'resolved' }),
      (error) => setState({ error, status: 'rejected' })
    )
  }, [pdfContents])

  if (status === 'pending') {
    return <Spinner />
  }

  if (status === 'rejected') {
    return <Error message={error} />
  }

  return <iframe title="PDF" src={pdf} />
}
React 구성 요소의 주요 역할은 React to render에 태그를 반환하는 것입니다. 그러나 이 예에서는 함수체의 절반을 해당 지점에 도달하기 전에 스크롤해야 합니다.조립품을 너무 많이 만든 것 같아.전화useReduceruseEffect의 목적이 무엇인지 아직 알 수 없다.
하나의 함수가 너무 길고 곤혹스러울 때, 좋은 방법은 그것을 몇 개의 더 짧고 집중적인 함수로 나누는 것이다.다른 구성 요소에서 더 많은 비동기 작업을 수행할 수 있기 때문에, 우선 불러오기, 오류, 성공 상태를 처리하는 논리를 함수에 추출합니다.(이하 내용은 this에서 영감을 얻었습니다.)
import React from 'react'

const useAsync = () => {
  const [{ status, data, error }, setState] = React.useReducer(
    (prevState, newState) => ({ ...prevState, ...newState }),
    { status: 'idle', data: null, error: null }
  )

  const run = React.useCallback((promise) => {
    if (!promise || !promise.then) {
      throw new Error(
        `The argument passed to useAsync().run must be a promise.`
      )
    }
    setState({ status: 'pending' })
    return promise.then(
      (data) => setState({ data, status: 'resolved' })
      (error) => setState({ error, status: 'rejected' })
    )
  }, [])

  return {
    isIdle: status === 'idle',
    isLoading: status === 'pending',
    isError: status === 'rejected',
    isSuccess: status === 'resolved',
    run,
    data,
    error,
  }
}
이것은 맞춤형 갈고리다.나는 그것이 단지 함수일 뿐이라는 것을 다시 한 번 지적하고 싶다.이것은 리액션 랜드에서 사용자 정의 갈고리라고 불린다. 왜냐하면 1)의 이름은 use로 시작하고, 2) 리액션 라이브러리에서 use로 시작하는 함수를 호출하기 때문이다.
이제 PDF 어셈블리를 다음과 같이 변경할 수 있습니다.

const generatePDF = (contents) => {
  // Generate PDF
  ...
  // Returns a promise
}

const PDF = ({ pdfContents }) => {
  const { data: pdf, isLoading, error, isError, run } = useAsync()
  React.useEffect(() => {
    run(generatePDF(pdfContents))
  }, [run, pdfContents])

  if (isLoading) {
    return <Spinner />
  }

  if (isError) {
    return <Error message={error} />
  }

  return <iframe title="PDF" src={pdf} />
}
이것은 훨씬 낫지만, 조립품을 너무 많이 만든 것 같다.다른 함수 useAsyncuseEffect 호출을 추출합시다.

const generatePDF = (contents) => {
  // Generate PDF
  ...
  // Returns a promise
}

const usePDF = (pdfContents) => {
  const { data: pdf, isLoading, error, isError, run } = useAsync()
  React.useEffect(() => {
    run(generatePDF(pdfContents))
  }, [run, pdfContents])
  return { pdf, isLoading, isError, error }
}

const PDF = ({ pdfContents }) => {
  const { pdf, isLoading, isError, error } = usePDF(pdfContents)

  if (isLoading) {
    return <Spinner />
  }

  if (isError) {
    return <Error message={error} />
  }

  return <iframe title="PDF" src={pdf} />
}
PDF 부품이 많이 좋아진 것 같아요.PDF를 생성하고 로드, 오류 및 성공 상태를 처리하는 모든 작업이 한 줄로 줄었기 때문에 구성 요소는 태그 렌더링에 집중할 수 있습니다.
현재 PDF 구성 요소의 기능은 매우 명확하다. 제공된 도구를 사용하여 PDF를 생성하고 Spinner, Error 또는 iframe의 PDF를 되돌려준다.useReduceruseEffect에 대한 모호한 호출을 풀려고 하지 않습니다.

이것은 무슨 새로운 일이 아니다


만약 우리가 React 프로그램에서 일하고 있다는 사실을 무시한다면, 앞의 예시를 잘 알고 있을 것입니다.마찬가지로 우리가 하는 일은 하나의 큰 기능을 더욱 작은 기능으로 분해하고 모든 기능은 하나의 단독 직책을 가진다.
이곳에는 새로운 것이 없다. 이것이 바로 맞춤형 갈고리가 이렇게 강한 이유다.그것은 단지 하나의 함수 (구성 요소) 로 다른 함수 ((usePDF 를 호출하고 더 많은 함수 (useAsyncuseEffect 를 호출할 뿐이다.React는 맞춤형 갈고리를 호출할 때 two rules 따르기만 하면 되지만, 이외에 함수에 대한 모든 직감은 즉시 적용될 수 있다.

더 나은 개발 도구


코드를 유지하기 쉽게 하는 것 외에 맞춤형 연결고리는react-dev 도구의 내용을 개선하여 응용 프로그램을 디버깅하기 쉽게 한다.
간단한 예를 하나 들자.사용자 등록 폼을 만들고 있다고 가정하십시오.당신은 어떻게 상태를 유지할 수 있습니까?나는 많은 코드가 이렇다는 것을 보았다.
import React from 'react'

const RegisterForm = ({ onSubmit }) => {
  const [username, setUsername] = React.useState('')
  const [firstName, setFirstName] = React.useState('')
  const [lastName, setLastName] = React.useState('')
  const [email, setEmail] = React.useState('')
  const [password, setPassword] = React.useState('')
  const [confirmPassword, setConfirmPassword] = React.useState('')

  return (
    <form>
      <input 
        value={username}
        onChange={(e) => setUsername(e.target.value)}
      />
      ...
    </form>
  )
}
좋습니다. 하지만 브라우저에서 React-dev 도구를 열면 다음과 같습니다.

이것은 그다지 큰 도움이 되지 않는다.이 상태들이 표에 속하는지는 아직 알 수 없다.
이 점을 더욱 명확하게 하기 위해서, 우리는 이 모든 useState 호출을 다른 함수로 추출할 수 있다.더 좋은 것은 모든 useState 통화를 한 useReducer 통화로 바꿀 수 있다는 것이다.
import React from 'react'

const useRegisterForm = () => {
  return React.useReducer(
    (prevState, newState) => ({ ...prevState, ...newState }),
    {
      username: '',
      password: '',
      confirmPassword: '',
      firstName: '',
      lastName: '',
      email: '',
    }
  )
}

const RegisterForm = ({ onSubmit }) => {
  const [registerForm, setRegisterForm] = useRegisterForm()

  return (
    <form>
      <input 
        value={registerForm.username}
        onChange={(e) => setRegisterForm({ username: e.target.value })}
      />
      ...
    </form>
  )
}
이제 개발 도구가 더욱 명확해졌습니다.
useRegisterForm 갈고리의 모든 상태가 RegisterForm 아래에 표시되어 있음을 주의하십시오.모든 맞춤형 갈고리는 이런 상황이 발생한다.useCustomHook라는 갈고리는 개발 도구에 CustomHook로 표시됩니다.

얼마


사용자 정의 갈고리는 매우 좋지만, 사용자 정의 갈고리로 상태를 얼마나 추출해야 합니까?
솔직히 말해서, 나는 네가 더욱 빈번하게 상태를 맞춤형 연결고리로 옮겨야 한다고 생각한다.우리가 논의한 바와 같이, 구성 요소의 가독성을 높이기 위해 관련 상태 부분을 함께 저장할 수 있습니다.게다가 다시 사용하고 개선할 수 있는 개발 도구가 가져온 추가적인 장점은 그것을 계속 사용하지 않는 것이 합리적이라는 것을 증명하기 어렵다.

결론


나는 맞춤형 고리가 얼마나 유용한지 깨닫는 데 시간이 걸렸지만, 일단 깨닫게 되면 다시는 돌아보지 않을 것이다.나는 지금 줄곧 그것들을 사용하고 있으며, 나의 코드도 이로 인해 더욱 좋아졌다.만약 응용 프로그램에서 사용자 정의 연결을 사용하지 않았다면, 시작하시기를 강력히 권장합니다.

좋은 웹페이지 즐겨찾기