I have the following code which should render the dropdown with a list of values once the data is fetched. I used a state value loading
to make the re-rendering work.
However, it does not re-render the dropdown after fetching the data. I tried some options which I found on StackOverflow using the useEffect
, but it makes my code run into an infinite error loop.
Below is the code:
//necessary imports
function Home(props){
const [role_options, setRoleOptions] = useState([])
const [is_loading, setIsLoading] = useState(true)
const set_roles=()=>{
let temp_data = []
Promise.resolve(get_roles()).then(value=>{
value.map((x,i)=>{
let eachx = {key:i,text:x,value:x}
temp_data.push(eachx)})
})
return temp_data
}
useEffect(()=>{
setRoleOptions(set_roles());
setIsLoading(false) ;
},[])
if(is_loading === true)
return ('Loading......')
return(
<ul className="dropdown-menu">
{role_options.map((role,i)=>{
<li key={role.key}>{role.text} {role.value}</li>
})}
</ul>
)
}
export default Home
I would also like to add that the above code works if I just change the <ul>, <li>
to Dropdown
from semantic-ui-react
. I have also tried <select>, <option>
HTML tags that also do not work. If I add role_options
as a dependency inside the useEffect
like below:
useEffect(()=>{
setRoleOptions(set_roles());
setIsLoading(false) ;
},[role_options])
This makes my code run into an infinite loop. Could anyone please tell me what will be the solution to what I am doing wrong here?
Also, this component is called in the App.js
file of React as one of the many components, and this Home
component is the first one which is called when the page loads after npm start
.
CodePudding user response:
Use your useEffect
like below, with an empty dependency array. I assume get_roles
is an asynchronous function, according to how you used it.
function Home(props) {
const [role_options, setRoleOptions] = useState([]);
const [is_loading, setIsLoading] = useState(true);
useEffect(() => {
get_roles().then((value) => {
const temp_data = value.map((x, i) => ({ key: i, text: x, value: x }));
setRoleOptions(temp_data);
setIsLoading(false);
});
}, []);
if (is_loading === true) return "Loading......";
return (
<ul className="dropdown-menu">
{role_options.map((role, i) => {
return (
<li key={role.key}>
{role.text} {role.value}
</li>
);
})}
</ul>
);
}
export default Home;
Your attempt is not working because temp_data
is returned before the promise is resolved. And another error, you are not returning anything in your map
.