简体   繁体   中英

How can I fetch and pass the result to the next fetch in react?

How can I fetch the version and languages and pass them to getChampions function

const [version, setVersion] = useState(0)
const [languages, setLanguages] = useState([])
const [selectedLanguage, setSelectedLanguage] = useState('')
const [champions, setChampions] = useState([])

useEffect(() => {
  getVersion().then((version) => setVersion(version))
    .then(getLanguages().then(languages => {
      setLanguages(languages)
      setSelectedLanguage(languages[0])
    }))
    .then(getChampions(version, selectedLanguage).then(champions => setChampions(champions)))
}, [])

I'm getting the default values from the initialization of useState where version = 0 and languages = []

You can use async await in a separate function to fetch the version and language and use the fetched version and language to fetch the champions data. Take a look at below example.

 const [version, setVersion] = useState(0) const [languages, setLanguages] = useState([]) const [selectedLanguage, setSelectedLanguage] = useState('') const [champions, setChampions] = useState([]) const fetchData = async () => { const versionData = await getVersion(); setVersion(versionData) const languageData = await getLanguages(); setLanguages(languageData) setSelectedLanguage(languageData[0]) const championsData = await getChampions(versionData, languageData[0]) setChampions(championsData) } useEffect(() => { fetchData(); }, [])

setState is asynchronous, so if you setState and then call a function with the state immediately after you are not guaranteed to get the current state value. @Yadab's answer resolves this but calling getChampions with the variables from the response rather than the variables from the state.

My personal preference is to use a separate hook to respond to changes in the state. It also seems like getVersion and getLanguages don't depend on each other and can be run simultaneously rather than one after the other.

const App = () => {
  const [version, setVersion] = useState(0);
  const [languages, setLanguages] = useState([]);
  const [selectedLanguage, setSelectedLanguage] = useState("");
  const [champions, setChampions] = useState([]);

  useEffect(() => {
    getVersion().then(setVersion);
  }, []); // run once - include [setVersion] if using eslint

  useEffect(() => {
    getLanguages().then((languages) => {
      setLanguages(languages);
      setSelectedLanguage(languages[0]);
    });
  }, []); // run once - can include deps [setLanguage, setSelectedLanguage] for eslint

  useEffect(() => {
    // only execute if both version and selectedLanguage have already been set
    if (version && selectedLanguage) {
      getChampions(version, selectedLanguage).then(setChampions);
    }
  }, [version, selectedLanguage]); // run whenever version or selected language changes

...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM