> 웹 프론트엔드 > CSS 튜토리얼 > 반응 서스펜스 : 데이터를로드하는 동안 배운 교훈

반응 서스펜스 : 데이터를로드하는 동안 배운 교훈

尊渡假赌尊渡假赌尊渡假赌
풀어 주다: 2025-03-18 10:18:15
원래의
998명이 탐색했습니다.

반응 서스펜스 : 데이터 로딩에서 배운 교훈

반응 서스펜스 : 데이터를로드하는 동안 배운 교훈

Spessense는 REACT의 다가오는 기능으로 데이터로드와 같은 비동기 작업을 조정하여 UI의 상태 불일치를 쉽게 방지 할 수 있습니다. 이것이 정확히 무엇을 의미하는지 더 자세히 설명하고 서스펜스에 대한 간단한 소개,보다 현실적인 사용 사례와 배운 교훈을 드리겠습니다.

내가 소개 한 기능은 여전히 ​​알파 단계에 있으며 생산 환경에서 사용해서는 안됩니다. 이 게시물은 다가오는 기능을 첫 번째로 살펴보고 미래로 향할 위치를 이해하려는 사람들을위한 것입니다.

서스펜스를 시작합니다

응용 프로그램 개발의 가장 어려운 부분 중 하나는 응용 프로그램 상태를 조정하는 것입니다. 상태 변경은 일반적으로 여러 위치에서 새로운 데이터로드를 트리거합니다. 일반적으로, 각 데이터는 자체로드 UI (예 : "회전기")가 있으며 대략 데이터가 응용 프로그램의 위치 인 위치입니다. 데이터로드의 비동기 특성은 이러한 요청이 어떤 순서로든 반환 될 수 있음을 의미합니다. 결과적으로, 다양한 스피너로 응용 프로그램이 나타나고 사라질뿐만 아니라 응용 프로그램에 일관성이없는 데이터가 표시 될 수 있습니다. 세 가지 데이터로드 중 2 개가 완료되면 세 번째 위치 상단에로드 스피너가 표시되어 여전히 오래된 구식 데이터가 표시됩니다.

나는 그것이 너무 많다는 것을 안다. 혼란스러워하는 것을 발견하면 내가 쓴 서스펜스에 관한 이전 기사에 관심이있을 수 있습니다. 이 기사는 서스펜스가 무엇인지, 무엇을 구현하는지보다 자세히 소개합니다. 이러한 작은 세부 사항 중 일부는 이제 구식입니다. 즉, useTransition 후크는 더 이상 timeoutMs 값을 받아들이지 않지만 무기한 기다립니다.

이제 세부 사항을 간단히 살펴본 다음 숨어있는 트랩이있는 특정 사용 사례로 넘어 갑시다.

서스펜스가 어떻게 작동하는지

다행스럽게도 React 팀은 데이터를로드하려는 이러한 노력을 제한하지 않을 정도로 똑똑합니다. 서스펜스는 저수준 프리미티브를 통해 작동하며 거의 모든 것에 적용 할 수 있습니다. 이 프리미티브를 간단히 살펴 보겠습니다.

가장 먼저<suspense></suspense> 경계, 그것은 fallback 속성을 허용합니다.

<suspense fallback="{<Fallback"></suspense> }>
로그인 후 복사
로그인 후 복사

이 구성 요소의 하위 구성 요소가 중단 될 때마다 fallback 만듭니다. 몇 개의 하위 구성 요소가 중단 되더라도 어떤 이유로 fallback 표시됩니다. 이것은 반응이 UI가 일관되도록 보장하는 한 가지 방법입니다. 모든 것이 준비 될 때까지 아무것도 렌더링하지 않습니다.

그러나 사용자가 상태를 변경하고 컨텐츠가 처음 렌더링 된 후 새 데이터를로드하면 어떻게됩니까? 우리는 확실히 우리의 기존 UI가 사라지고 우리의 fallback 보여주기 를 원하지 않습니다 . 대신 새 UI가 표시되기 전에 모든 데이터가 준비 될 때까지 로딩 스피너를 표시 할 수 있습니다.

useTransition 후크는 이것을 구현합니다. 이 후크는 함수와 부울 값을 반환합니다. 우리는 기능을 호출하고 상태 변경을 감싸줍니다. 이제 상황이 흥미로워지고 있습니다. React는 상태 변경을 적용하려고합니다. 뭐든지, 반응은 부울 값을 true 로 설정하고 행이 끝날 때까지 기다립니다. 완료되면 상태 변경을 다시 적용하려고합니다. 어쩌면 이번에는 성공하거나 다른 것이 매달릴 것입니다. 어쨌든, 부울 깃발은 모든 것이 준비 될 때까지 true 유지하며, 만 상태 변경이 완료되고 UI에 반영 될 것입니다.

마지막으로, 우리는 어떻게 매달려 있습니까 ? 우리는 약속을 던져서 매달립니다. 데이터가 요청되고 가져와야한다면, 우리는 가져 와서 그 페치와 관련된 약속을 던집니다. 이 저수준 중단 메커니즘은 우리가 무엇이든 사용할 수 있음을 의미합니다. 게으른 하중 구성 요소에 대한 React.lazy 유틸리티는 이미 서스펜스와 함께 작동하며, 컨텐츠가 움직이지 않도록 UI를 표시하기 전에 이미지가로드 될 때까지 서스펜스를 사용하기 전에 작성했습니다.

걱정하지 마세요, 우리는이 모든 것에 대해 논의 할 것입니다.

우리는 무엇을 만들고 있습니까?

우리는 다른 유사한 기사의 예와 약간 다른 것을 만들 것입니다. 서스펜스는 여전히 알파 단계에 있으므로 좋아하는 로딩 데이터 유틸리티에는 아직 서스펜스 지원이 없을 수 있습니다. 그렇다고해서 우리가 무언가를 속일 수없고 서스펜스가 어떻게 작동하는지 이해한다는 의미는 아닙니다.

일부 데이터를 표시하고 서스펜스를 기반으로 일부 사전로드 된 이미지를 결합하는 무한로드리스트를 작성하겠습니다. 더 많은 데이터를로드하는 버튼뿐만 아니라 데이터를 표시합니다. 데이터가 렌더링되면 관련 이미지를 사전로드하고 준비되기 전에 매달릴 것입니다.

이 유스 케이스는 내 사이드 ​​프로젝트에서 수행 한 실제 작업을 기반으로합니다 (다시 한 번 생산에 서스펜스를 사용하지 말고 측면 프로젝트는 허용됩니다). 나는 당시 내 자신의 GraphQL 클라이언트를 사용하고 있었고이 게시물의 동기는 내가 가진 어려움 중 일부였습니다. 단일 데이터로드 유틸리티가 아닌 운영을 단순화하고 서스펜스 자체에 집중하기 위해 데이터로드를 위조합니다.

건축을 시작하십시오!

이것은 우리가 처음 시도한 샌드 박스입니다. 우리는 그것을 사용하여 모든 것을 단계별로 설명하기 위해 사용하므로 모든 코드를 이해하기 위해 서두르지 않아도됩니다.

루트 App 구성 요소는 다음과 같은 서스펜스 경계를 ​​렌더링합니다.

<suspense fallback="{<Fallback"></suspense> }>
로그인 후 복사
로그인 후 복사

fallback 아무것도 걸릴 때마다 렌더링됩니다 ( useTransition CALL에서 상태 변경이 발생하지 않는 한). 일을 쉽게 이해하기 위해이 Fallback 구성 요소 전체를 UI 핑크 전체를 돌리 셨기 때문에 우리의 목표는 고품질 UI를 구축하는 대신 서스펜스를 이해하는 것입니다.

우리는 DataList 구성 요소 내부에 현재 데이터 블록을로드하고 있습니다.

 const newdata = usequery (param);
로그인 후 복사

우리의 useQuery hook는 시뮬레이션 된 네트워크 요청에 대한 시간 초과를 포함하여 가짜 데이터를 반환하도록 하드 코딩되었습니다. 캐시 된 결과를 처리하고 데이터가 캐시되지 않으면 약속을 던집니다.

우리는 우리가 표시하는 메인 데이터 목록에 상태 (적어도 현재)를 저장합니다.

 const [data, setData] = usestate ([]);
로그인 후 복사

새로운 데이터가 우리의 후크에서 전달되면 메인 목록에 추가됩니다.

 useeffect (() => {
  setData ((d) => d.concat (newData));
}, [newData]);
로그인 후 복사
로그인 후 복사

마지막으로 사용자가 더 많은 데이터가 필요할 때이 기능이라고하는 버튼을 클릭합니다.

 함수 loadmore () {
  startTransition (() => {
    setparam ((x) => x 1);
  });
}
로그인 후 복사

마지막으로 SuspenseImg 구성 요소를 사용하여 각 데이터가 표시되는 이미지의 예압을 처리합니다. 5 개의 임의의 이미지 만 표시되지만 쿼리 문자열이 추가되어 새로운 데이터가 겪는 각 데이터마다 새로운 부하가 만들어 졌는지 확인했습니다.

요약

현재 위치를 요약하기 위해 현재 데이터를로드하는 후크가 있습니다. 이 후크는 서스펜스 메커니즘을 따르고 로딩이 발생할 때 약속을 던집니다. 해당 데이터가 변경 될 때마다 실행중인 프로젝트의 총 목록이 업데이트되고 새 프로젝트가 첨부됩니다. 이것은 useEffect 에서 발생합니다. 각 프로젝트는 이미지를 렌더링하고 SuspenseImg 구성 요소를 사용하여 이미지를 사전로드하고 준비되기 전에 매달립니다. 일부 코드가 어떻게 작동하는지 궁금한 점이 있으면 서스펜스가있는 이미지를 사전로드하는 내 이전 게시물을 확인하십시오.

테스트합시다

모든 것이 잘 작동하면 이것은 매우 지루한 블로그 게시물이 될 것입니다. 걱정하지 마십시오. 정상이 아닙니다. 핑크 fallback 화면이 표시되고 초기 하중에서 빠르게 숨겨져 있지만 다시 디스플레이됩니다.

더 많은 데이터를로드하기 위해 버튼을 클릭하면 인라인로드 표시기 ( useTransition 후크로 제어)가 true 로 플립이 표시됩니다. 그런 다음 우리는 그것이 false 으로 뒤집 히고 원래의 분홍색 fallback 디스플레이를 표시합니다. 초기 하중 후에는 핑크 스크린이 더 이상 나타나지 않을 것으로 예상합니다. 무슨 일이에요?

질문

눈에 띄는 곳에 숨겨져 있습니다.

 useeffect (() => {
  setData ((d) => d.concat (newData));
}, [newData]);
로그인 후 복사
로그인 후 복사

상태 변경이 완료되면 useEffect 실행됩니다. 그 부분은 "완료된 보류"가 여기서 핵심입니다. 우리가 원한다면 여기에 상태를 설정할 수 있지만, 그 상태 변화가 다시 매달려 있다면 그것은 새로운 교수형입니다. 그렇기 때문에 초기로드 및 후속 데이터로드 후 핑크색이 깜박임이 발생합니다. 두 경우 모두 데이터 로딩이 완료된 다음 상태를 한 가지 효과로 설정하여 이미지가 사전로드되어 새 데이터가 실제로 렌더링되고 다시 매달려 있습니다.

그렇다면이 문제를 어떻게 해결합니까? 한 수준에서 솔루션은 간단합니다. 효과에서 상태를 설정하지 마십시오. 그러나 이것은 말보다 쉽습니다. 효과를 사용하지 않고 새로운 결과를 첨부하기 위해 실행중인 항목 목록을 어떻게 업데이트합니까? 당신은 우리가 참조를 사용하여 물건을 추적 할 수 있다고 생각할 수도 있습니다.

불행히도 Spessense는 심판에 대한 새로운 규칙을 제시합니다. 즉, 렌더 내부에 심판을 설정할 수 없습니다. 왜 그런지 궁금하다면, 서스펜스는 반응이 렌더를 실행하려고 시도하고, 약속이 던져지는 것을보고, 중간에 렌더링하는 것을 버린다는 것을 기억하십시오. 렌더링이 취소되고 폐기되기 전에 심판을 변경하면 심판은 여전히 ​​그 변화가 있지만 잘못된 값을 가지고 있습니다. 렌더링 기능은 순수해야하며 부작용이 없습니다. 이것은 항상 React의 규칙 이었지만 이제는 더 중요합니다.

데이터로드를 다시 생각하십시오

이것은 해결책입니다. 단락으로 단락을 설명 할 것입니다.

먼저 기본 데이터 목록을 주에 저장하는 대신 다른 작업을 수행하십시오.보고있는 페이지 목록을 저장합시다. 가장 최근의 페이지를 Ref에 저장할 수 있습니다 (렌더로 쓰지는 않지만) 현재로드 된 모든 페이지 배열을 주에 저장할 수 있습니다.

 const currentPage = useref (0);
const [pages, setPages] = usestate ([currentPage.Current]);
로그인 후 복사

더 많은 데이터를로드하려면 다음에 따라 업데이트합니다.

 함수 loadmore () {
  startTransition (() => {
    CurrentPage.Current = CurrentPage.Current 1;
    setPages ((pages) => pages.concat (currentpage.current));
  });
}
로그인 후 복사

그러나 까다로운 부분은이 페이지 번호를 실제 데이터로 변환하는 방법입니다. 우리가 할 수없는 것은이 페이지를 통해 루프를 사용하고 루프에서 고리 useQuery 호출 할 수 없습니다. 새로운 비 훅 기반 데이터 API가 필요합니다. 과거의 서스펜스 데모에서 본 매우 비공식적 인 협약에 따르면, 나는이 방법을 read() 라고 불렀습니다. 후크가 아닙니다. 데이터가 캐시되면 요청 된 데이터를 반환하면 약속이 발생합니다. 우리의 가짜 데이터로드 훅의 경우, 실제로 변경할 필요가 없었습니다. 그러나 실제 데이터로드 유틸리티 라이브러리의 경우 저자가 공개 API의 일부로 두 옵션을 모두 노출시키는 데 약간의 작업이 필요할 수 있습니다. 앞에서 언급 한 GraphQL 클라이언트에는 실제로 클라이언트 객체에 useSuspenseQuery hook와 read() 메소드가 모두 있습니다.

이 새로운 read() 메소드를 사용하면 코드의 마지막 부분은 사소합니다.

 const data = pages.flatmap ((page) => read (page));
로그인 후 복사

각 페이지를 가져 와서 read() 메소드를 사용하여 해당 데이터를 요청합니다. 어떤 페이지가 캐시되지 않은 경우 (실제로 목록의 마지막 페이지에만 가능해야 함) 약속이 던져져 반응이 우리에게 매달릴 것입니다. Promise Parses가되면 React는 이전 상태 변경을 다시 시도 하며이 코드는 다시 실행됩니다.

flatMap Call이 당신을 혼란스럽게하지 마십시오. 새로운 배열에서 모든 결과를 얻고 배열 자체 인 경우 "평평한"을 제외하고는 map 과 똑같은 일입니다.

결과

이러한 변경으로 시작하면 모든 것이 예상대로 작동합니다. 우리의 핑크 로딩 화면은 초기로드에서 한 번 표시 된 다음 후속 로딩에서 모든 것이 준비 될 때까지 인라인 로딩 상태가 표시됩니다.

결론

서스펜스는 반응하기위한 흥미로운 업데이트입니다. 여전히 알파 단계에 있으므로 중요한 것을 위해 사용하려고하지 마십시오. 그러나 당신이 다가오는 컨텐츠를 처음으로 경험하는 것을 좋아하는 종류의 개발자라면,이 게시물이 게시시 유용한 유용한 배경과 정보를 제공하기를 바랍니다.

위 내용은 반응 서스펜스 : 데이터를로드하는 동안 배운 교훈의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿