IT이야기

리액션 후크 사용 방법내 경우 한 번만 효과?

cyworld 2022. 3. 11. 22:26
반응형

리액션 후크 사용 방법내 경우 한 번만 효과?

한동안 내 질문이 중복된 것 같은데 아닌 것 같아, 제목이 같지만 케이스가 다른 질문들을 많이 확인했어.

문제는 내 코드에 리액션 훅을 두 번 사용할 수 밖에 없었고 세 번으로 만들려고까지 생각했지만, 나쁜 관행은 주변에 일이 있거나 해결책이 있다고 확신한다.

처음에 가져오려는 데이터가 있고 먼저 사용효과 호출에 의해 나중에 데이터를 필터링하거나 정렬할 수 있으며 필터 확인란과 정렬 쿼리를 위한 선택 항목이 있으며 확인란을 선택하면 데이터가 필터링되고 옵션을 선택하면 해당 데이터가 정렬되며, 이 트리를 만들기 위해 Redex 및 react-relensx 연결 방법을 사용하고 있다.루데스 필터sortBy

  //the first call
  useEffect(() => {
    loadProducts();
  }, []);


//the second call
  useEffect(() => {
    loadProducts(filters, sortBy)
  }, [filters, sortBy])

const mapStateToProps = (state) => ({
  filters: state.filters,
  sortBy: state.sortBy
});


const mapDispatchToProps = (dispatch) => ({
  loadProducts: (filters, sortBy) => {
    fetch('certain API').then(res => res.json()).then(json => {
      dispatch(fetchProducts(json.products, filters, sortBy));
    }).catch(err => 'error fetching data');
  }
});

이제 첫 번째 호출은 API에서 데이터를 검색하는 것이고 loadProducts 함수는 인수가 필요하지 않으며, 두 번째 호출은 필터링이나 정렬을 수행할 때 인수가 필요하고 필터 또는 sortBy가 변경될 때 작동한다.

두 번째 전화를 이렇게 두 가지 통화로 나누어서 세 가지 통화로 만들 생각마저 든다.

 useEffect(() => {
    loadProducts(filters)
  }, [filters])

useEffect(() => {
    loadProducts(undefined, sortBy)
  }, [sortBy])

그리고 그 이유는 오직 하나만 작동해야 할 때에도 매번 필터링과 정렬이 일어나기를 원하지 않기 때문이다.왜냐하면 나는 정렬이 사용자만 데이터를 적합시킬 때뿐만 아니라 그 반대의 경우도 효과가 있을 것이라고 생각하기 때문이다.

다음은 내 petchProducts 작업:

import { filterProducts, sortProducts } from './../../util/util';
export const fetchProducts = (products, filters, sortBy) => {
    if (filters && filters.length) {
        products = filterProducts(products, filters);
    }

    if (sortBy) {
        sortProducts(products, sortBy);
    }

    return {
        type: FETCH_PRODUCTS,
        payload: products
    }
}

petchProducts에서 제품을 변이하는 경우 좋은 방법이 아님products = sortProducts([...products], sortBy);대신에

상태의 초기 값.필터는[]sortBy의 초기 값은 false 또는 working default sort이며, 그러면 하나의 효과만 있으면 된다.

스카이보일러의 설명대로, 사용자가 필터를 변경하거나 정렬할 때 비동기 처리를 할 경우 레이스 상태를 피해야 한다.

다음과 같은 방법으로 효과를 작성할 수 있다.

useEffect(() => {
  const cancel = {current:false};
  //add cancel, only dispatch fetchProducts when it's
  //  the latest result from user interaction
  loadProducts(filters, sortBy, cancel);
  return ()=>cancel.current=true;
  //added loadProducts as an effect dependency
  //  the linter should have warned you about it
}, [filters, loadProducts, sortBy])

const mapDispatchToProps = (dispatch) => ({
  loadProducts: (filters, sortBy, cancel) => {
    fetch('certain API').then(res => res.json()).then(json => {
      //only dispatch if this is the latest list of products
      //  if user changed something during fetching then don't
      //  set products
      cancel.current || dispatch(fetchProducts(json.products, filters, sortBy));
    }).catch(err => 'error fetching data');
  }
});

필터가 초기인 경우[]그리고 sortBy는 처음에 작업 가치를 가지고 있거나 또는 그것이 단지 작동되어야만 하는 거짓이다.

모든 논리를 한 번에 처리하려면useEffect전화, 모든 지원 의존성을 제거할 수 있다.[filters, sortBy]from useEffect.

useEffect(() => {
  //This runs all the time a component (re)renders
});

이제 내부는useEffect프로펠러 변경에 따라 조건부로 가져오기 작업을 호출해야 한다.사용할 수 있다useRef소품의 이전 가치를 추적하기 위해.아래의 대략적인 초안.

function App(props){
  const {products = [], filter, sortBy} = props;
  const filterRef = useRef();
  const sortRef = useRef();
  const loadedRef = useRef(false); 


  // The effect runs all the time
  useEffect(() => {
    if(!loadedRef.current){
      console.log("Dispatch the loadProducts action");
      //Update ref
      loadedRef.current =  true;
    }else{
      if(sortBy !== sortRef.current){
        console.log("Dispatch the filter action");
        // Update ref
        sortRef.current = sortBy;
        // return after this line if you want to avoid next if condition;
      }
      if(filter !== filterRef.current){
        console.log("Dispatch the sort action");
        //Update ref
        filterRef.current = filter;
      }
    }
  });


  return <div>{products.map(product => <h1>{product}</h1>)}</div>
}

참조URL: https://stackoverflow.com/questions/58568334/how-to-use-react-hook-useeffect-only-once-in-my-case

반응형