मेरे पास एपीआई से देशों की सरणी लाने के लिए कुछ हुक है:

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

const useCountries = () => {
 const dispatch = useDispatch()

 const { countries } = useSelector(data => data)

 useEffect(() => {
   if (!countries.length) {
     dispatch(getCountries())
   }
 }, [countries])

  return {
    countries
  }
}

मेरे पास कुछ घटक हैं जो DOM के समान स्तर पर नहीं हैं, और एक दूसरे से संबंधित नहीं हैं

const FirstComponent = () => {
  const {countries} = useCountries()

  // some using of countries array
}

const SecondComponent = () => {
  const {countries} = useCountries()

  // some using of countries array
}

जब इन घटकों में से 2 पृष्ठ लोड हो रहे हैं, निष्पादित होते हैं, और 2 क्रियाएं भेजी जाती हैं। क्योंकि देशों को अभी तक पहले और दूसरे घटक में नहीं चुना गया है, यह एपीआई अनुरोध को कॉल करता है। मेरा सवाल है, अगर कुछ अनुरोध भेजा गया था तो मैं दूसरा अनुरोध भेजने से कैसे रोक सकता हूं। केवल एक बार रिक्वेस्ट भेजने के लिए कुछ नियम बनाएं, अगर दूसरी बार भेजने की कोशिश करें तो उसे ब्लॉक कर दें। या मेरे मामले में सही समाधान या दृष्टिकोण क्या है?

इसके अलावा, मैंने इस तरह के एक मामले की कोशिश की है:

  const {
    external: { response, isInitial }
  } = useSelector(data => data)

  useEffect(() => {
    if (!response && isInitial) {
      dispatch(setIsInitial(false))

      fetch()
        .then(res => res.json())
        .then(data => {
           setResponse(data)
        })
    }
  }, [dispatch, response, isInitial])

यहाँ मेरा रेड्यूसर है:

const initialState = {
  response: null,
  isInitial: true
}

export default function external(state = initialState, action) {
  switch (action.type) {
    case types.SET_RESPONSE:
      return {
        ...state,
        response: action.payload.data
      }
    case types.SET_INITIAL:
      return {
        ...state,
        isInitial: action.payload.data
      }

    default:
      return state
  }
}

लेकिन यह 2 अनुरोध भेजता है

2
Andrey Radkevich 26 मार्च 2020, 12:26

2 जवाब

सबसे बढ़िया उत्तर

आप अपने useCountries को निम्नानुसार संशोधित कर सकते हैं:

const useCountries = () => {
 const dispatch = useDispatch()

 const countries  = useSelector(state => state.countries);
 const isFetching = useSelector(state => state.isFetching);

 useEffect(() => {
   if (!countries.length && !isFetching) {
     dispatch(getCountries()) 
   }
 }, [countries, isFetching])

  return {
    countries
  }
}

आपको अपने getCountries फ़ंक्शन में isFetching ध्वज को फ़्लिप करना होगा और api के हल होने पर इसे फिर से फ़्लिप करना होगा।

------------------ अतिरिक्त जानकारी के बाद संपादित करें ----------------------

आपको अपनी dispatch कॉलों को श्रृंखलाबद्ध करना होगा। यह सुनिश्चित करने के लिए है कि आप एपीआई कॉल करने से पहले ध्वज सेट कर दिया गया है।

इसे प्राप्त करने के लिए आप निम्नलिखित तरीके से dispatch को फिर योग्य बना सकते हैं।

dispatch दो में से कोई एक लौटाता है:

समन्वयन क्रिया के लिए (जैसे प्रेषण ({प्रकार: 'कार्रवाई'}) यह मेरे उदाहरण में क्रिया वस्तु ({प्रकार: 'कार्रवाई'} लौटाएगा)

थंक क्रियाओं के लिए (एक्शन क्रिएटर जो फ़ंक्शन लौटाते हैं) यह वही परिणाम देता है जो एक्शन क्रिएटर से लौटाया जाता है।

यह पहला मामला है।

const syncAction = (arg1, arg2) => {
    return (dispatch, getState) => {
        return Promise.resolve(arg1 + arg2);
    }
}

यह दूसरा मामला होगा।

const asyncAction = (arg1, arg2) => {
  return (dispatch, getState) => {
    return fetch(/* some request */)
      .then(response => dispatch({ type: "RESPONSE_RECEIVED", payload: response }));
  };
};

अब उपरोक्त दो से लैस होकर, आप निम्न कार्य कर सकते हैं:

dispatch(syncAction(...args)).then(() => {
    dispatch(asyncAction())
});

आपके मामले में syncAction - isInitial और asyncAction - getCountries()

1
Utsav Patel 26 मार्च 2020, 15:14

प्रभाव निर्भरता सरणी का उपयोग करने के लिए dispatch जोड़ें जो समस्या को हल करेगा।

 const dispatch = useDispatch()

 const { countries } = useSelector(data => data)

useEffect(() => {
   if (!countries.length) {
     dispatch(getCountries())
   }
 }, [countries, dispatch])
0
Ebleme 11 फरवरी 2021, 08:58