programing

React useEffect에 종속성 배열의 스프레드 요소가 있음

prostudy 2022. 3. 28. 21:41
반응형

React useEffect에 종속성 배열의 스프레드 요소가 있음

비동기 호출의 로딩 및 오류 동작을 처리할 사용자 지정 후크를 만들려고 한다.

나는 그것을 그렇게 사용하고 싶다.

const { loading, error} = useFetch(fetchUser, id)

또는

const {loading, error } = useFetch(updateUserName, id, name)

나는 지금까지 이렇게 생긴 것을 가지고 있다.

function useFetch(fetchFn, ...params) {
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(false);

  useEffect(() => {
    fetchFn(...params)
      .then(() => {
        setLoading(false);
      })
      .catch(() => {
        setError(true);
      });
  }, [...params, fetchFn]);

  return { loading, error };
}

나는 그 일에 어려움을 겪고 있다.useFetch(fetchFn, ...params)신출내기부터params모든 통화 시 배열 생성그래서 나는 그것을 종속 배열에서 사용할 수 없다.하지만 스프레드 오퍼레이터는 사용할 수 없어.

내가 하고자 하는 일을 성취하는 것이 가능한가?

편집: 이제 리액션 쿼리를 사용하고 내 삶은 더 단순하다.

나는 간신히 원하는 행동을 할 수 있었다.

function useFetch(fetchFn, ...params) {
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(false);

  useEffect(() => {
    fetchFn(...params)
      .then(() => {
        setLoading(false);
      })
      .catch(() => {
        setError(true);
      });
  }, params);

  return { loading, error };
}

나는 그냥 지나간다.params종속 배열로.물론 eslint는 행복하지 않지만 우리는 간단히 그것을 무력화할 수 있다.나는 이 구현이 옳다고 믿는다.

의견을 자유롭게 공유하십시오. 피드백에 정말 관심이 있습니다,

아마도 당신은 개별 매개변수가 그러한 매개변수의 배열이 아니라 종속성이 되기를 원하십니까?왜냐하면 이 경우 종속성은 실제로 어레이 인스턴스일 뿐이기 때문이다(자신의 말대로 매번 변경될 것이다).

종속성 목록에 매개 변수를 분산하지 말고 종속성 목록에 해당 매개 변수를 포함하십시오.

useEffect(() => {
  fetchFn(...params)
    .then(() => {
      setLoading(false);
    })
    .catch(() => {
      setError(true);
    });
}, [fetchFn].concat(params));

이렇게 하는 게 어때?

주의: 이 코드는 실행 가능한 코드가 아니다.그것은 심지어 전치되지도 않았다.그것은 코드 부분이 부족해서 아마 오타가 많을 것이다.참고용으로만 사용하십시오.

/*
Firstly, let's define a function to determine if two arrays have the same elements.
*/
const hasSameValues = (arr1 = [], arr2 = []) => {
  if (arr1?.length !== arr2?.length) {
    return false;
  }

  for (let i = 0, length = arr1?.length; i < length; i++) {
    if (arr1[i] !== arr2[i]) {
      return false;
    }
  }
  return true;
}

/* 
 Now we define the compoenent that will receive the dependencies array
*/

const AircraftComboBox = ({source = () => {}, dependencies = [], onChange = () => {}}) => {
  
  // Let's save the dependencies to evaluate if they've changed in the next render
  const [storedDependencies, setStoredDependencies] = useState(dependencies);

  const [availableAircrafts, setAvailableAircrafts] = useState([]);

  useEffect(
    () => {
      // Use the hasSameValues function to determine in runtime if the array of dependecies has changed
      setStoredDependencies(prev => hasSameValues(prev, dependencies) ? prev : dependencies)
    },
    [dependencies, setStoredDependencies] // this array of dependencies still hardcoded
  );

  useEffect(() => {
    async function fetchData() {
      const response = await source(); // Call the source function passed in props
      setAvailableAircrafts([...response.data]);
    }
    
    fetchData();
  }, [storedDependencies]); // this array of dependencies still hardcoded


  return (
    <>
      <label for="aircrafts-combo">Aircraft</label>
      <select id="aircrafts-combo" onChange={e => onChange(e)}>
        { availableAircrafts.map(option => <option value={option}>{option}</option>) }
      </select>
    </>  
  );
}



/**
  Now we can use it.
  Note that the Component using AircraftComboBox doesn't need to implement any useEffect.
 */
 const AircraftFeature = () => {
   const [category, setCategory] = useState('');
   const [airCraft, setAircraft] = useState('');

   return (
     <>
      <div>
        <label for="category">Category</label>
        <select id="category" type="text" onChange={e => setCategory(e.target.value)} >
          <option value="ac">airplane</option>
          <option value="rc">rotorcraft</option>
          <option value="pl">powered lift</option>
          <option value="gl">glider</option>
          <option value="lta">lighter than air</option>
          <option value="pp">powered parachute</option>
          <option value="wsc">weight-shift-control</option>
        </select>  
      </div>

    {/**
     Every time category's change, source function, defined in props, will be fired.
     This will retrieve new data to populate the list of available options.
     */}

      <AircraftComboBox 
        source={() => httpService.getAirplanesByCategory(category)}
        dependencies={[category]}
        onChange={e => setAircraft(e.target.value)}
      /> 

    </>
   );
 }

참조URL: https://stackoverflow.com/questions/59107782/react-useeffect-has-a-spread-element-in-its-dependency-array

반응형