programing

react use객체 비교 효과

lastmoon 2023. 2. 26. 10:27
반응형

react use객체 비교 효과

리액트 사용 중useEffect후크 및 객체 변경 여부를 확인한 후 후 후크를 다시 실행합니다.

제 코드는 이렇게 생겼어요.

const useExample = (apiOptions) => {
    const [data, updateData] = useState([]);
    useEffect(() => {
       const [data, updateData] = useState<any>([]);
        doSomethingCool(apiOptions).then(res => {               
           updateData(response.data);
       })
    }, [apiOptions]);

    return {
        data
    };
};

안타깝게도 객체가 동일한 것으로 인식되지 않기 때문에 계속 실행됩니다.

그 이유는 다음과 같습니다.

const objA = {
   method: 'GET'
}

const objB = {
   method: 'GET'
}

console.log(objA === objB)

아마 실행 중일 것이다JSON.stringify(apiOptions)작동합니까?

사용하다apiOptions상태 가치로서

커스텀 훅을 어떻게 소비하고 있는지 모르겠지만apiOptions이용함으로써 상태값useState잘 될 겁니다이렇게 하면 다음과 같은 상태 값으로 커스텀훅에 제공할 수 있습니다.

const [apiOptions, setApiOptions] = useState({ a: 1 })
const { data } = useExample(apiOptions)

이 방법으로는 사용했을 때에만 달라집니다.setApiOptions.

예 #1

import { useState, useEffect } from 'react';

const useExample = (apiOptions) => {
  const [data, updateData] = useState([]);
  
  useEffect(() => {
    console.log('effect triggered')
  }, [apiOptions]);

  return {
    data
  };
}
export default function App() {
  const [apiOptions, setApiOptions] = useState({ a: 1 })
  const { data } = useExample(apiOptions);
  const [somethingElse, setSomethingElse] = useState('default state')

  return <div>
    <button onClick={() => { setApiOptions({ a: 1 }) }}>change apiOptions</button>
    <button onClick={() => { setSomethingElse('state') }}>
      change something else to force rerender
    </button>
  </div>;
}

또는

당신은 깊이 비교되는 것을 쓸 수 있다.useEffect다음 설명과 같이 합니다.

function deepCompareEquals(a, b){
  // TODO: implement deep comparison here
  // something like lodash
  // return _.isEqual(a, b);
}

function useDeepCompareMemoize(value) {
  const ref = useRef() 
  // it can be done by using useMemo as well
  // but useRef is rather cleaner and easier

  if (!deepCompareEquals(value, ref.current)) {
    ref.current = value
  }

  return ref.current
}

function useDeepCompareEffect(callback, dependencies) {
  useEffect(
    callback,
    dependencies.map(useDeepCompareMemoize)
  )
}

사용하는 것처럼 사용할 수 있습니다.useEffect.

나는 방금 나에게 맞는 해결책을 찾았다.

사용하셔야 합니다.usePrevious()그리고._.isEqual()Lodash에서.내부useEffect(), 앞의 조건을 붙였습니다. apiOptions시류와 같다 apiOptions사실이라면 아무것도 하지 마세요.false updateData()의 경우.

예:

const useExample = (apiOptions) => {

     const myPreviousState = usePrevious(apiOptions);
     const [data, updateData] = useState([]);
     useEffect(() => {
        if (myPreviousState && !_.isEqual(myPreviousState, apiOptions)) {
          updateData(apiOptions);
        }
     }, [apiOptions])
}

usePrevious(value)를 작성하는 커스텀훅입니다.ref와 함께useRef().

Official React Hook 문서에서 찾을 수 있습니다.

const usePrevious = value => {
  const ref = useRef();
  useEffect(() => {
    ref.current = value;
  });
  return ref.current;
};

입력이 충분히 얕아서 완전한 평등이 여전히 빠르다고 생각되는 경우JSON.stringify:

const useExample = (apiOptions) => {
    const [data, updateData] = useState([]);
    const apiOptionsJsonString = JSON.stringify(apiOptions);

    useEffect(() => {
       const apiOptionsObject = JSON.parse(apiOptionsJsonString);
       doSomethingCool(apiOptionsObject).then(response => {               
           updateData(response.data);
       })
    }, [apiOptionsJsonString]);

    return {
        data
    };
};

기능은 비교되지 않습니다.

만약 당신이 정말로 통제할 수 없다고 확신한다면apiOptionsnative useEffect를 https://github.com/kentcdodds/use-deep-compare-effect으로 대체하기만 하면 됩니다.

어떤 경우에는 정말 간단해!

const objA = {
   method: 'GET'
}

const objB = {
   method: 'GET'
}

console.log(objA === objB) // false

objAobjB와 같지 않은 이유는 무엇입니까?Coz JS는 주소만 비교하면 되는 거죠?두 개의 다른 obj입니다.우리 모두 다 알아요!

리액트 훅이랑 똑같아!

우리 모두 알다시피, objA.메서드 === objB.방법, 맞죠?문자 그대로니까.

답은 다음과 같습니다.

React.useEffect(() => {
    // do your facy work
}, [obj.method])

Deep Compare Effect를 사용하거나 Custom Compare Effect를 사용하거나 자체 후크를 작성할 수 있습니다.

https://github.com/kentcdodds/use-deep-compare-effect https://github.com/sanjagh/use-custom-compare-effect

다른 하나의 옵션(변경할 수 있는 경우)doSomethingCool:

정확히 알 수 있다면Object필요한 속성을 사용하여 종속성 목록을 다음과 같은 속성으로 제한할 수 있습니다.useEffect로 올바르게 해석하다===예:

const useExample = (apiOptions) => {
    const [data, updateData] = useState([]);
    useEffect(() => {
       const [data, updateData] = useState<any>([]);
        doSomethingCool(apiOptions.method).then(res => {               
           updateData(response.data);
       })
    }, [apiOptions.method]);

    return {
        data
    };
};

언급URL : https://stackoverflow.com/questions/54095994/react-useeffect-comparing-objects

반응형