I'm trying to generate an array of random words fetched from an API and then update for new ones when clicking on a button, right now i can update the array with new words but cant seem to know how to rerender the component after updating the array. Ive achieved a way but it updates the words, word by word when the loop goes through them and what I want is a way to update all the words at once when the all the words are fetched.
Sorry if ive had a hard time explaning myself, but english is not my native language.
Here is what i have for now with words updatting but not at the same time:
const [words, setWords] = useState([]);
const throwDices = () => {
words.map((word, index) => {
fetch("https://palabras-aleatorias-public-api.herokuapp.com/random")
.then((response) => {
if (response.ok) {
return response.json();
}
throw Response;
})
.then((data) => {
words[index] = data.body.Word;
setWords([...words]);
});
});
};
useEffect(() => {
throwDices();
}, []);
This answer is inspired by this article
const [words, setWords] = React.useState();
const callApiTenTimes = async () => {
// create an array of promises
let promises = [];
for (let i = 0; i < 10; i++) {
promises.push(fetch("https://palabras-aleatorias-public-api.herokuapp.com/random"));
}
// wait for all promises to fulfill
Promise.all(promises)
.then((responses) =>
// Get a JSON object from each of the responses
Promise.all(responses.map((res) => res.json()))
)
.then((data) => {
// Get all the data and store it in our useState
const results = data.map(({ body }) => body.Word);
setWords(results);
})
.catch((err) => console.warn(err));
};
// On first render when words === undefined, call API once to fetch first 10 words
useEffect(() => {
if (!words) {
callApiTenTimes();
}
}, [words]);
return (
<>
{/* render each word in the word array */}
{words.map((word) => (
<p>{word}</p>
))}
{/* get new words after a button click */}
<button onClick={() => callApiTenTimes()}>Get new words</button>
</>
)