Home > other >  React: how can I add states that are objects into a single array and access it?
React: how can I add states that are objects into a single array and access it?

Time:10-12

I made two API calls in separate useEffect functions in order to come up with two homophones (one that I've hard coded, and the other from the second API call).

I want to combine the two object states(ourWord, homophone) into one array so that I can set it to definition state and use it in JSX. I put the key value in each object, hoping that somehow I can use conditional logic to access one of them, but I'm having trouble to do any of the above.

const [ourWord, setOurWord] = useState({word: '', definition: ''});
  const [homophone, setHomophone] = useState({word: '', definition: ''});
  const [definition, setDefinition] = useState('');

// First useEffect API call to return ourWord state, which is an object with word and its definition
  useEffect( () => {
    axios({
      url: `https://api.dictionaryapi.dev/api/v2/entries/en/${startingWord}`,

    })
    .then(res => {
      setOurWord({
        key: 0,
        word: res.data[0].word,
        definition: res.data[0].meanings[0].definitions[0].definition
      });
    })
  }, [])
  

  // Second useEffect API call to return a homophone object 
  useEffect( () => {  
    axios({
      url: 'https://api.datamuse.com/words',
      method: 'GET',
      dataResponse: 'json',
      params: {
        md: "d",
        rel_hom: startingWord,
      }
    }).then(homophone => {

      const wordWithDefinition = homophone.data.filter(homophone => homophone.defs);
      setHomophone({
        key: 1,
        word: wordWithDefinition[0].word, 
        definition: wordWithDefinition[0].defs[0]
      })

    })
  }, []);

CodePudding user response:

If I understand you correctly, then you can use Promise.all():

const [combineDefinitions, setCombineDefinitions] = useState([])

useEffect(() => {
    const promise1 = axios({
        url: `https://api.dictionaryapi.dev/api/v2/entries/en/${startingWord}`,

    })
    const promise2 = axios({
        url: 'https://api.datamuse.com/words',
        method: 'GET',
        dataResponse: 'json',
        params: {
            md: "d",
            rel_hom: startingWord,
        }
    })
    Promise.all([promise1, promise2]).then(([resultFromPromise1, resultFromPromise2])=>{
        const arr = [];
        arr.push({
            key: 0,
            word: resultFromPromise1.data[0].word,
            definition: resultFromPromise1.data[0].meanings[0].definitions[0].definition
        })
        const wordWithDefinition = resultFromPromise2.data.filter(homophone => homophone.defs);
        arr.push({
            key: 1,
            word: wordWithDefinition[0].word,
            definition: wordWithDefinition[0].defs[0]
        })
        setCombineDefinitions(arr)
    });
}, [])

CodePudding user response:

Since setState is asynchronous, you should combine the useEffects:

useEffect( () => {
    let combined = []
    axios({
      url: `https://api.dictionaryapi.dev/api/v2/entries/en/${startingWord}`,

    })
    .then(res => {
      combined = [
        ...combined,
        {key: 0,
        word: res.data[0].word,
        definition: res.data[0].meanings[0].definitions[0].definition}
      ]
    })

     axios({
      url: 'https://api.datamuse.com/words',
      method: 'GET',
      dataResponse: 'json',
      params: {
        md: "d",
        rel_hom: startingWord,
      }
    }).then(homophone => {
      const wordWithDefinition = homophone.data.filter(homophone => homophone.defs);
      combined = [
        ...combined,
        {key: 1,
        word: wordWithDefinition[0].word, 
        definition: wordWithDefinition[0].defs[0]}
      ]
    })
    setCombined(combined)
  }, [])
  • Related