Reputation: 105
I am using Reactjs. When I console log randomData
I expect the output to be a random text from the data
and then I want to loop over it. But the result is strange and getting 2 different outputs for each log. When I am out of the useEffect
I can't even Array.prototype.map()
over randomData
or use String.prototype.split("")
.
PS: I know that If I log inside the useEffect
it will only render once, but How I get the data(each text) out of the useEffect then I can use it to loop over?
source: https://codesandbox.io/s/react-playground-forked-3bd7z
import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";
function App() {
const data = [
{
id: 1,
text: "hello world"
},
{
id: 2,
text: "hi world"
},
{
id: 3,
text: "hola"
},
{
id: 4,
text: "oo"
}
];
const [randomData, setRandomData] = useState(data);
useEffect(() => {
let randomIndex = Math.floor(Math.random() * randomData.length);
setRandomData(randomData[randomIndex].text);
}, []);
console.log(randomData);
console.log(typeof randomData);
return (
<div className="App">
{/* {data.map(item => console.log((item.text).split("").map(letter => letter)))} */}
{/* {console.log(typeof randomData)} */}
</div>
);
}
Upvotes: 0
Views: 227
Reputation: 4207
Your problem with the duplicate output is because you are assigning the data
to randomData
initially. React then rerenders (yielding the first console output) and only then calls your useEffect hook.
I would propose you don't use useEffect at all but instead an initialization function for useState
:
const [randomData, setRandomData] = useState(()=>{
let randomIndex = Math.floor(Math.random() * data.length);
return data[randomIndex].text;
});
This way the data is set during the first render, not after it.
EDIT: If the data
is coming from an external api, useEffect
is the right choice. In that case you start fetching in useEffect
and then set the state once you have the data. Initialize the state to your preferences, (I'd go with useState(null)
) and handle your render accordingly, because until you have data, randomData
will not contain anything.
Upvotes: 2