2019년 비동기식 부작용 처리 방법

21856 단어 reactjavascript
작성자 Peter Ekene Eze✏️
비동기적인 조작을 처리하는 것은 React 생태계에서 개발자들이 주목하는 주요 문제이다.
여러 가지 다른 방법으로 비동기적인 조작을 처리하는데 Redux Saga를 포함하지만 본고에서 우리는 현재 가장 좋은 방법인 사용react-async을 중점적으로 주목할 것이다.
라이브러리와 React에서 비동기 부작용을 처리하는 다른 기존 방법도 비교할 것입니다.

React Async란 무엇입니까?


React Async는 약속을 기반으로 하는 도구로 약속을 성명 방식으로 처리하고 데이터를 얻을 수 있습니다.
비동기식 UI 상태를 쉽게 처리할 수 있으며 데이터의 형태나 요청 유형을 가정할 필요가 없습니다.
React-Async는 React 구성 요소와 몇 개의 연결로 구성되어 있습니다.fetch, Axios, GraphQL 및 기타 데이터 가져오기 라이브러리와 함께 사용할 수 있습니다.
React-async는 성명 문법, JSX,native promises를 사용하여 코드에 필요한 위치에 더 가까운 데이터 (예를 들어 구성 요소 수준) 를 해석하는 데 의존합니다. 이것은 다른 시스템 (예를 들어 Redux) 과 달리 Redux는 응용 프로그램에서 조작과 복원기 등 더 높은 수준의 해석 데이터를 사용합니다.

비동기식 사용 반응


다음 예제에서처럼 React-Async를 사용하려면 react-async 에서 useAsync 를 가져옵니다.
그리고 우리는 비동기 함수를 만들 수 있다. 이 함수는 신호를 매개 변수로 수신한다.신호는 AbortController API로 필요할 때 호출을 취소할 수 있는 방법을 제공합니다.
구성 요소에서, 우리는 react-async 를 호출하여 비동기 함수를 전달합니다.
호출 useAsync 은 대상을 되돌려줍니다. 우리는 그것을 세 가지 중요한 값으로 분해할 수 있습니다. 데이터, error, isPending입니다.
이 값들은 비동기 함수의 상태를 알려 줍니다. - 끊겼는지, 틀렸는지, 성공했는지 알려 줍니다.
이러한 값 중 하나를 사용하여 사용자에게 적절한 UI를 제공할 수 있습니다.
import { useAsync } from "react-async"
// You can use async/await or any function that returns a Promise
const asyncFn = async ({ signal }) => {
  const res = await fetch(`/api/users`, { signal })
  if (!res.ok) throw new Error(res.statusText)
  return res.json()
}
const MyComponent = () => {
  const { data, error, isPending } = useAsync({ promiseFn: asyncFn })
  if (isPending) return "Loading..."
  if (error) return `Something went wrong: ${error.message}`
  if (data)
    <ul>
      {data.users.map(user => <li>{user.name}</li>)}
    </ul>
)
return null
React Async를 사용하면 문서 로깅이 가능한 몇 가지 방법이 있습니다.
  • 연결
  • 벨트useAsync
  • 어셈블리로 사용
  • 공장으로
  • 보조 구성 요소 포함
  • 의 정적 특성
    저는 앞의 세 가지 방법을 간략하게 소개할 것입니다. 단지 당신에게 이러한 실현을 이해하게 하기 위해서입니다. 그러나 official usage guide를 참고하여 모든 방법을 깊이 있게 이해하십시오.

    갈고리로 비동기적으로 반응하다


    React-Async는 useFetch라는 갈고리를 제공합니다.어셈블리에서 다음과 같이 연결을 호출할 수 있습니다.
    import { useAsync } from "react-async";
    
    const MyComponent = () => {
      const { data, error, isPending } = useAsync({ promiseFn: loadPlayer, playerId: 1 })
      //...
    };
    

    useAsync 비동기식 반응 사용

    useFetch를 사용하면 나중에 어셈블리에서 실행할 수 있는 비동기식 가져오기 함수를 생성합니다.
    import { useFetch } from "react-async"
    const MyComponent = () => {
      const headers = { Accept: "application/json" }
      const { data, error, isPending, run } = useFetch("/api/example", { headers }, options)
      // You can call "handleClick" later
      function handleClick() {
        run()
      }
    <button onClick={handleClick}>Load</button>
    }
    

    구성 요소로 비동기식 반응


    다음은 JSX에서 React Async가 제대로 작동하는 부분입니다.
    import Async from "react-async"
    const MyComponent = () => (
      <Async promiseFn={load}>
        {
          ({ data, error, isPending }) => {
            if (isPending) return "Loading..."
            if (error) return `Something went wrong: ${error.message}`
            if (data)
              return (<div> { JSON.stringify(data, null, 2) }</div>)
            return null
          }
        }
      </Async>
    )
    
    함수를 서브레벨로 useFetch 어셈블리에 전달해야 합니다.
    보시다시피 이 함수는 우리가 도구로 제공한 비동기 함수의 상태에 따라 서로 다른 노드 값을 평가할 것입니다.

    반응 비동기와 비동기

    AsyncAsync/Await와의 결합은 React Async보다 편리하지 않습니다. 특히 경쟁 조건을 고려하고 정리를 처리하며 끊긴 비동기적인 작업을 취소할 때입니다.
    React Async는 매우 효율적인 방식으로 이 모든 일을 처리합니다.
    사용 useEffect 및 비동기식/대기 처리 경쟁의 일반적인 사례를 살펴보겠습니다.
    const [usersList, updateUsersList] = useState();
    useEffect(() => {
      const runEffect = async () => {
        const data = await fetchUsersList(filter);
        updateUsersList(data);
      };
      runEffect();
    }, [updateUsersList, filter]);
    
    상술한 상황에서 만약에 어떤 이유로든 우리는 useEffect 두 번 호출해야 하고, 두 번째 호출useEffect은 첫 번째 호출 전에 해결해야 한다. 그러면 우리는 유행이 지난'업데이트'목록을 얻을 것이다.
    필요할 때 useEffect 호출을 방지하기 위해 이 문제를 해결할 수 있는 방법을 추가할 수 있지만, 이러한 방법은 여러 fetchUsersList 표현식과 잘 확장되지 않을 수 있습니다.
    다른 한편, React Async를 사용할 때 해결되지 않은 요청을 취소하거나 적절한 경쟁 조건을 처리할 염려가 없습니다. React가 이러한 문제를 처리했기 때문입니다.
    import { useAsync } from "react-async"
    // You can use async/await or any function that returns a Promise
    const fetchUsersList = async ({ signal }) => {
      const res = await fetch(`/api/users`, { signal })
      if (!res.ok) throw new Error(res.statusText)
      return res.json()
    }
    const filteredUsers = (users) => {
      // Filter users ...
    }
    const MyComponent = () => {
      const { data, error, isPending } = useAsync({ promiseFn: fetchUsersList})
      if (isPending) return "Loading..."
      if (error) return `Something went wrong: ${error.message}`
      if (data)
      <ul>
        { filteredUsers(data.users).map(user => <li>{user.name}</li>) }
      </ul>
    )
    return null
    
    위의 코드 세션에서 언제든지 updateUsersList 을 호출하면 await 구성 요소를 다시 보여 줍니다. 이것은 우리가 항상 예상한 상태를 가지고 있음을 의미합니다.
    또한 React-Async는 내부 정리를 하고 fetchUsersList API를 사용하여 해결되지 않은 약속 (즉 MyComponent 함수에 전달된 AbortController 변수) 을 취소합니다. 따라서 경쟁 조건을 걱정할 필요도, 더 이상 필요하지 않은 해결되지 않은 약속을 취소할 필요도 없습니다.
    만약 응용 프로그램이 매우 기초적이고 14kb 라이브러리를 추가하여 비동기적인 조작을 처리하는 것이 의미가 없다면, signal의 더욱 높은 실현에 만족할 수 있습니다.
    내가 보기에 React-Async는 이미 상당히 경량급이어서 좋은 테스트를 거친 것 외에도 많은 장점이 있다.
    따라서 14kb 절감에서 얻는 수익이 중요하지 않으면 React-Async를 사용할 수 있습니다.

    React Async vs Redux Saga

    fetchUsersList는 애플리케이션 부작용(예: 데이터 수집 및 불순물, 브라우저 캐시 액세스 등)을 관리하기 쉽고 효율적이며 테스트하기 쉽고 고장 처리를 향상시키기 위한 라이브러리입니다. redux-saga.js.org.
    Redux 전설은 React Async보다 더 많은 절차를 거쳐야 시작할 수 있습니다.
    이것은 Redux 중간부품이기 때문에 Redux를 설정해야 한다는 것을 의미합니다.
    Redux의 생각은 응용 프로그램의 모든 부분이나 주요 부분에 집중 상태를 제공하는 것이다.이렇게 하면 스케줄링useEffect을 통해 상태를 업데이트할 수 있습니다.예:
    const Counter = ({ value }) =>
      <div>
        <button onClick={() => store.dispatch({type: 'INCREMENT_ASYNC'})}>
          Increment after 1 second
        </button>
        <hr />
        <div>
          Clicked: {value} times
        </div>
      </div>
    
    Redux Saga는 "ES6 생성기"에 의존하여 네트워크 호출이나 기타 비동기식 부작용을 방지합니다.
    function* incrementAsync() {
      yield delay(1000)
      yield put({ type: 'INCREMENT' })
    }
    
    보시다시피 어디서 부작용을 일으키는지는 당신들의 구성 요소를 멀리하는 것입니다.구성 요소 내에서 스케줄링 작업을 통해 업데이트를 터치할 수 있습니다.그리고 업데이트 상태는 당신의 아이템을 통해 입장합니다.
    매우 표준적인 것이지만 React Async가 제공하는 것과는 매우 다르고 직관적이지도 않다.

    결론

  • React Async를 사용합니다. Redux를 사용하는 것처럼 데이터의 외관을 가정할 필요가 없습니다.이것은 네가 통상적으로 약속을 사용하는 것과 같다.
  • React Async를 사용하면 데이터를 더 가까운 위치로 해석하여 무슨 일이 일어났는지 더욱 명확하게 알 수 있습니다.
  • 귀약기와 동작 같은 구조를 포함하고 있는 상당히 복잡한 구조를 이해할 필요가 없다. 이미 알고 있는 구성 요소에 사용되는 JSX, Promises, Hooks를 이용할 수 있다.
    편집자: 이 문장에 무슨 문제가 있습니까?정확한 버전here을 찾을 수 있습니다.

    플러그인: 네트워크 어플리케이션용 DVR용 LogRocket


     

     
    LogRocket는 프런트엔드 로그 기록 도구로 자신의 브라우저에서처럼 문제를 재생할 수 있다.LogRocket은 오류가 발생한 원인을 추측하거나 화면 캡처와 로그 저장을 물어보지 않고 세션을 다시 재생할 수 있도록 합니다.프레임워크가 어떻든지 간에 모든 응용 프로그램과 완벽하게 어울릴 수 있으며, 플러그인은 Redux, Vuex, @ngrx/store의 추가 상하문을 기록합니다.
     
    LogRocket은 Redux 작업과 상태를 기록하는 것 외에도 콘솔 로그, JavaScript 오류, 스택 추적, 헤더+본문이 있는 네트워크 요청/응답, 브라우저 메타데이터와 사용자 정의 로그를 기록합니다.또한 DOM은 페이지의 HTML과 CSS를 기록하여 가장 복잡한 단일 페이지 응용 프로그램이라도 픽셀 수준의 비디오를 재구성합니다.
     
    Try it for free .
    게시물How to handle async side effects in 2019이 먼저 LogRocket Blog에 올라왔다.

    좋은 웹페이지 즐겨찾기