Reputation: 843
Let's say I've 3 screens,
HomeScreen
, which contains list of usersUserProfileScreen
, which contains user details and their postsPostDetailScreen
, which contains details about post@Composable
fun HomeScreen() {
LazyColumn {
// Show user profiles
}
}
@Composable
fun UserProfileScreen(
userId: Long,
userProfileViewModel: UserProfileViewModel
) {
LaunchedEffect(Unit) {
userProfileViewModel.getProfileAndPosts(userId)
}
UserProfileView()
LazyColumn {
// Show posts
}
}
@Composable
fun PostDetailScreen(
postId: Long,
postViewModel: PostViewModel
) {
LaunchedEffect(Unit) {
postViewModel.getPost(postId)
}
PostView()
}
When I move from HomeScreen
to UserProfileScreen
, I use LaunchedEffect(Unit) {}
to fetch user profile and posts from network. And if I click on any post, it will navigate to PostDetailScreen
and display post details.
Now, If I come back to UserProfileScreen
(via backpress), it will re-fetch the user data because getProfileAndPosts()
is a function and accept userId
so (I guess) can't be cached to viewModelScope
(If it were variable without any parameter, we can cache it)
How do I avoid that? Instagram seems to does exactly that. It does not re-fetch data. Though, they're on XML view, but it should not make any difference.
Upvotes: 2
Views: 3290
Reputation: 715
If I understand your problem correctly
You must use ViewModel. And define a data class with this name:
data class UserProfileState(
val wereThePostsReceived : Boolean = false,
val posts : List<Post> = emptyList()
)
And change its value to true after successfully receiving the posts in ViewModel.
fun getProfileAndPosts(userId : String) {
viewModelScope.launch {
val result = getPostsUseCase(userId)
when(result) {
is Succuss -> {
state = state.copy(
wereThePostsReceived = true,
posts = // your interactor , usecase result
)
is Failed -> {
}
}
}
Then use it in the Compose layout as follows:
LaunchedEffect(wereThePostsReceived) {
if(wereThePostsReceived == false){
postViewModel.getProfileAndPosts(postId)
}
}
Upvotes: 3