IT

use Selector의 파괴와 여러 콜의 파괴

itgroup 2023. 3. 4. 14:43
반응형

use Selector의 파괴와 여러 콜의 파괴

최근에 react-displex docs https://react-redux.js.org/next/api/hooks를 읽고 있었는데, Equality Comparison and Updates 관련 섹션이 있었습니다.이 섹션에는 다음과 같은 내용이 있습니다.

use Selector()를 여러 번 호출하여 각 호출이 단일 필드 값을 반환합니다.

첫 번째 접근법:

const { open, importId, importProgress } = useSelector((importApp) => importApp.productsImport);

두 번째 접근법:

const open = useSelector((importApp) => importApp.productsImport.open);
const importId = useSelector((importApp) => importApp.productsImport.importId );
const importProgress = useSelector((importApp) => importApp.productsImport.importProgress);

그래서 진짜 차이가 있나요?또는 useDestruction으로 인해 Selector Hook이 참조 확인에 문제가 발생합니까?

: 때, 합니다.useSelector()되는 이 액션이 렌더링됩니다.반환되는 값이 액션이 마지막으로 디스패치되었을 때 반환된 값과 다를 경우 컴포넌트는 다시 렌더링됩니다.

파괴하는 것은 잘못된 접근법이지만, 여기서 가장 중요한 답은 전혀 관련이 없습니다.매번 를 참조하고 은, 「」의 「신규 오브젝트 」의와 같습니다.mapStateToProps()기능.실제 데이터가 변경되지 않았더라도 셀렉터에 의해 반환되는 값은 엄밀히 말하면 메모리 내의 다른 개체이기 때문에 액션이 디스패치될 때마다 컴포넌트가 재렌더됩니다.이 경우 엄격한 평등과 얕은 평등 비교를 걱정할 필요가 있습니다.그러나 셀렉터가 매번개체를 만드는 것은 아닙니다.디스패치된 액션이 수정되지 않는 경우importApp.productsImport메모리의 오브젝트가 이전과 완전히 같게 되어, 이 모든 것이 렌더링 됩니다.

대신 실제로는 해당 슬라이스의 일부 속성에만 관심이 있을 때 전체 상태를 선택하는 것이 문제입니다.라고 생각해 .importApp.productsImport 그 외에도 다른 open,importId , , , , 입니다.importProgress다른 속성이 변경되면 컴포넌트는 참조하지 않아도 불필요하게 재렌더됩니다.가 반환하는 것은 '실렉터'입니다.실렉터가 반환됩니다.importApp.productsImport 그이 바뀌었어요.는 알 .open,importId , , , , 입니다.importProgress이러한 속성을 선택하지 않고 개체 전체를 선택했기 때문에 실제로 관심을 갖는 유일한 속성입니다.

솔루션

따라서 불필요한 재렌더 없이 여러 속성을 선택하려면 다음 두 가지 옵션이 있습니다.

  • 개의 " " " 를 합니다.useSelector()후크, 각각 스토어의 단일 자산을 선택합니다.
  • useSelector()후크 및 스토어의 여러 속성을 하나의 객체로 결합하는 단일 선택기.을 사용하다
    • 다시 선택에서 메모된 셀렉터를 사용합니다.
    • 의 특정 에서 새 .state반품합니다.이렇게 하면 엄격한 평등과 얄팍한 평등 비교에 대해 걱정해야 합니다.

위해서 저는 여러 가지 생각이 .useSelector()훅은 사실 갈 수 있는 방법이에요. 라고 있다

useSelector()를 호출할 때마다 Redux 스토어에 대한 개별 서브스크립션이 생성됩니다.

그러나, 복수의 콜이 실제로 1개의 콜에 비해 퍼포먼스 저하가 발생하는지는, 이러한 이유만으로 알 수 있다고 생각합니다.또, 수백, 수천개의 서브 스크라이브를 가지는 대규모 앱을 가지고 있지 않는 한, 이것에 대해 염려하는 것은 아마 과잉 최적화라고 생각됩니다.의 " " " 를 useSelector(),, 러, 러, 그, 그, ,, ,, ,, ,, ,, ,, ,, ,, ,, ,, ,, ,, ,, ,, ,, ,, ,, ,, ,, ,, ,, ,, ,,mapStateToPropsTypeScript를 쓰고 있는 경우, 특히 후크를 사용하는 것의 매력을 크게 꺾는 것 같은 느낌입니다.그리고 그 결과를 파괴하고 싶다면, 그것은 훨씬 더 번거로운 일입니다.또한 여러 훅을 사용하는 것이 Hooks API의 일반적인 정신에 더 가깝다고 생각합니다.

작업이 Redux 저장소에 디스패치되면 useSelector()는 엄격한 "===" 참조 비교만 수행합니다.이것은 얄팍한 체크는 하지 않습니다.

따라서 스토어에서 여러 값을 가져오려면 useSelector()를 여러 번 호출해야 합니다.각 콜은 스테이트에서1개의 필드 값을 반환합니다. 「」를 사용합니다.shallowEqualreact-redux

import { shallowEqual, useSelector } from 'react-redux'

const data = useSelector(state => state.something, shallowEqual)

상세한 것에 대하여는, https://react-redux.js.org/next/api/hooks#equality-comparisons-and-updates 를 참조해 주세요.

이 답변에는 기술적인 세부 사항이 많지 않습니다.이해를 돕기 위해 다른 답변을 검토하십시오.여기서는 사용 사례 시나리오만 언급하고 있습니다.도움이 되기를 바랍니다.

전제 조건: 제품 Import에는 사용자가 언급한 필드(open, importId, importProgress)만 있습니다.

1. useSelector를 사용하여 단일 컴포넌트의 모든 필드를 취득한다고 가정하면 First Approach를 사용해야 합니다.세컨드 어프로치를 사용하면 코드 행이 몇 줄 추가되지만 다른 이점은 없습니다.필드 값이 업데이트될 때마다 구성 요소가 다시 렌더링됩니다.

2. 한 컴포넌트(Component1)에서 importId를 사용하고 다른 컴포넌트(Component2)에서 나머지 필드를 갱신하고 있다고 가정합니다.또한 이러한 구성요소는 동일한 창/화면에 렌더링되어야 합니다.그런 다음 두 번째 방법을 사용해야 합니다.

Component1:
    const importId = useSelector((importApp) => importApp.productsImport.importId );

Component2:
 const open = useSelector((importApp) => importApp.productsImport.open);
 const importProgress = useSelector((importApp) => importApp.productsImport.importProgress);
 
if you want to use only one selector:
const [open, importProgress] = useSelector((importApp) =>[importApp.productsImport.open, importApp.productsImport.importProgress], 
shallowEqual);
'Note: Here do not forget to use shallowEqual. Otherwise, your component will rerender on every useSelector() call.'

여기서 First 어프로치를 사용하는 경우 필드를 갱신할 때마다 양쪽 컴포넌트가 재렌더됩니다.

여러 상태를 선택하는 방법:

const [village, timeZone, date] = useSelector((state) => [
    state.active_village,
    state.time_zone,
    state.date,
  ], shallowEqual);

퍼포먼스의 관점에서 보면 첫 번째 접근법이 더 낫습니다.후드 아래에서 파괴 코드는 다음과 같이 변환됩니다.

var temp = useSelector((importApp) => importApp.productsImport);
var open = temp.open;
var importId = temp.importId;
var importProgress = temp.importProgress;

두 번째 방법에서는 3회 접속하여 운영 비용이 더 많이 듭니다.

언급URL : https://stackoverflow.com/questions/59072200/useselector-destructuring-vs-multiple-calls

반응형