асинхронное программирование в js
пишу социальную сеть на react nodejs, когда захожу в аккаунт в sessionStorage формируется токен,при каждой перезагрузке токен изменяется на рандомную строку. По этому токену запрашиваю из базы, скажем, друзей.Столкнулся с такой проблемой, http запрос происходит до изменения или формирования токена по этому из базы не получаю желаемые данные. Как понимаю нужно организовать асинхронность, пробовал при помощи async/await но не получилось, не понимаю как нужно реализовать задачу
//компонент
function FriendComponent(props) {
const [load, setLoad] = useState(true)
useEffect(()=>{
if(load == true){
let key = sessionStorage.currentUser
//обновляю токен во время перезагрузки
props.dispatch(loadProfile(key,props.history))
//загружаю полученные данные из базы
props.dispatch( updateFriends())
setLoad(false)
}
})
console.log(props.friends.friendList);
const classes = useStyles();
return (
<div className={classes.root}>
<CssBaseline />
<ToolBar/>
<NavBar/>
<main className={classes.content}>
<div className={classes.toolbar}></div>
<h4>{props.friends.friendList.length===0?"You don't have any friends":`You have ${props.friends.friendList.length} friends`}</h4>
<h4 style={props.friends.friendList.length===0?{display:'block'}:{display:'none'}}>You can search for friends <Link to='/profile/search'>here</Link></h4>
<Paper elevation={3} className='friendlist'>
{
props.friends.friendList.map(item=>{
return(
<Card className={classes.root2} key={item.id}>
<CardActionArea>
<CardMedia
component="img"
alt="Contemplative Reptile"
height="140"
image={`http://localhost:5000/${item.photo}`}
title="Contemplative Reptile"
/>
<CardContent>
<Typography gutterBottom variant="h5" component="h2">
{item.name} {item.surname}
</Typography>
</CardContent>
</CardActionArea>
<CardActions>
<Button onClick={()=>props.dispatch(deletaFromFriends(item.id))} size="small" color="primary">
delete
</Button>
<Button onClick={()=>props.dispatch(goToProfile())} size="small" color="primary">
see profile
</Button>
</CardActions>
</Card>
)
})
}
</Paper>
</main>
</div>
)
};
export default connect(r=>r)(FriendComponent);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
Ответы (2 шт):
Как я понял, Вы хотите обновить токен строго ДО того, как загружать данные. Я сталкивался с похожей проблемой
Как мне кажется, Вам поможет такая минимальная модификация кода:
//компонент
async function FriendComponent(props) {
const [load, setLoad] = useState(true)
useEffect(()=>{
if(load == true){
let key = sessionStorage.currentUser
//обновляю токен во время перезагрузки
await props.dispatch(loadProfile(key,props.history))
//загружаю полученные данные из базы
props.dispatch( updateFriends())
setLoad(false)
}
})
console.log(props.friends.friendList);
const classes = useStyles();
return (
<div className={classes.root}>
<CssBaseline />
<ToolBar/>
<NavBar/>
<main className={classes.content}>
<div className={classes.toolbar}></div>
<h4>{props.friends.friendList.length===0?"You don't have any friends":`You have ${props.friends.friendList.length} friends`}</h4>
<h4 style={props.friends.friendList.length===0?{display:'block'}:{display:'none'}}>You can search for friends <Link to='/profile/search'>here</Link></h4>
<Paper elevation={3} className='friendlist'>
{
props.friends.friendList.map(item=>{
return(
<Card className={classes.root2} key={item.id}>
<CardActionArea>
<CardMedia
component="img"
alt="Contemplative Reptile"
height="140"
image={`http://localhost:5000/${item.photo}`}
title="Contemplative Reptile"
/>
<CardContent>
<Typography gutterBottom variant="h5" component="h2">
{item.name} {item.surname}
</Typography>
</CardContent>
</CardActionArea>
<CardActions>
<Button onClick={()=>props.dispatch(deletaFromFriends(item.id))} size="small" color="primary">
delete
</Button>
<Button onClick={()=>props.dispatch(goToProfile())} size="small" color="primary">
see profile
</Button>
</CardActions>
</Card>
)
})
}
</Paper>
</main>
</div>
)
};
export default connect(r=>r)(FriendComponent);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
Mожно сделать async функцию внутри useEffect, и запустить там же.