Full Guide to Jetpack Compose Effect Handlers

  Рет қаралды 88,055

Philipp Lackner

Philipp Lackner

Күн бұрын

The new effect handlers in Jetpack Compose can be quite a pain to deal with if you don't fully understand their purpose. However, they're super important to write performant Jetpack Compose code without side-effects.
This video once and for all goes through all these effect handlers, so you'll know what it's about afterwards.
⭐ Get certificates for your future job
⭐ Save countless hours of time
⭐ 100% money back guarantee for 30 days
⭐ Become a professional Android developer now:
pl-coding.com/premium-courses...
💻 Let me personally review your code and provide individual feedback, so it won't backfire and cost you a fortune in future:
elopage.com/s/philipplackner/...
Subscribe to my FREE newsletter for regular Android, Kotlin & Architecture advice!
pl-coding.com/newsletter
Join this channel to get access to perks:
/ @philipplackner
Regular live codings on Twitch:
/ philipplackner
Join my Discord server:
/ discord
Regular programming advice on my Instagram page: / _philipplackner_
Checkout my GitHub: github.com/philipplackner
You like my free content? Here you can buy me a coffee:
www.buymeacoffee.com/philippl...
00:00 - What is a side-effect?
03:34 - LaunchedEffect
09:11 - rememberCoroutineScope
11:08 - rememberUpdatedState
13:03 - DisposableEffect
15:53 - SideEffect
17:20 - produceState
19:12 - derivedStateOf
22:51 - snapshotFlow

Пікірлер: 117
@re7650
@re7650 2 жыл бұрын
Philipp is forever invited to my home for dinner. Such nice content and delivery.
@PhilippLackner
@PhilippLackner 2 жыл бұрын
❤️
@thegreatwarrior4989
@thegreatwarrior4989 2 жыл бұрын
For me you are the best channel for Android development
@PhilippLackner
@PhilippLackner 2 жыл бұрын
Thanks a lot!
@bro_chenzox
@bro_chenzox 2 жыл бұрын
+++++
@k4ba
@k4ba Жыл бұрын
@@PhilippLackner Thanks to you bro, resourceful people are often bad teachers cause of human nature, you in other hand are damn smart and brilliant in the way you explain
@mithilmehta1501
@mithilmehta1501 11 ай бұрын
Same for me.. 😂, I think this man deserves half of our salary 😂. Thanks @PhilippLackner!
@alindo23
@alindo23 Жыл бұрын
The only 2 I found useful were LaunchedEffect and DisposableEffect. The rest of them were created to make the interviews harder.
@allanandliftedhands2669
@allanandliftedhands2669 2 жыл бұрын
I always check on my notifications to make sure i did not miss a new video from this guy
@alihosseinnezhad2957
@alihosseinnezhad2957 2 жыл бұрын
Thank you Philipp , You explain contents with interesting examples. Here is one of the best channel for android. 👏👏
@vedx
@vedx 2 жыл бұрын
I was struggling with this. Thanks for the video ❤️❤️
@danielkeyes3931
@danielkeyes3931 2 жыл бұрын
Thanks for the video. I appreciated all the examples and the simplicity of them for easier understandability.
@kepper103
@kepper103 10 ай бұрын
THANK YOU SO MUCH, just this afternoon i was duct taping together my own event system from snippets of code i found online, but the one you show in LaunchedEffect part is so much better and cleaner! Thanks! The rest of the video is also great as well!
@OnlineEntrepreneurTools
@OnlineEntrepreneurTools Жыл бұрын
Thanks for this! Although my mind couldn't absorb any of the discussed effect. Part 1 to 9 is clear and easy to follow as a newbie of Jetpack Compose. This part (Part 10) doesn't have any relevance in almost all discussed subjects in parts 1 to 9 that's why I couldn't comprehend. Maybe this should be moved in a more advanced playlist for compose. I will just skip to the next part hopefully I am not totally lost as I really love the tutorials. I'll take note on this effect handlers and when I got to the point when I already need this subject then I'll just get back here. Thanks Philipp! Cheers!
@brunofreitas561
@brunofreitas561 Жыл бұрын
I had the same feeling!
@peterfraga4023
@peterfraga4023 Жыл бұрын
same kinda difficult... tried finding the prepared code (samples) to go over it... and couldn't find it. The code qould help, thought of buying the premium course, but if I don't understand the frrebee, not sure I will understand the paid course...) having the code wouldn't deter me from purchasing the paid course, maybe it would motivate me more
@namncc5413
@namncc5413 Жыл бұрын
​ 😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😅😮😮😮😮😮
@namncc5413
@namncc5413 Жыл бұрын
​@Peter Fraga 😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮ㅣ😅😅😅😅😮😮😅😮ㅣ😮ㅣ😮😮😮😮😮😮😅😮😮😮😮😮😮😮😮😅ㅣ😅😮😮😮😮😮😮ㅑ😅😅😅😅😅😅😅😅😮😅😅😅😮😮😮😅😮😅😮😮😮😮😅😅😅😮ㅣ😮😮😅😅😅😅😅😅😅😅😅😅😅😅😅😅😅😅😮😅ㅏ😅😅😅😮😅😅😅😅😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😅😮😮😅😅😅😅😮ㅣ😮ㅣ😮😮😮😮😮😮😮😅😅😅😅😮😮😮😅😮😮😮😮😅😮😮😅😅😅😮😮😮😮😮😮😮😮😮😮😮😅😅😮😮😮😮😅😮😮😮😮😮😮😮😮😮
@namncc5413
@namncc5413 Жыл бұрын
😮😮😮😮😮😮😮😮😮😮😮😮😅😮😅😅😅😅😅😮😮😮😮😮😮😮😮😮😮😮😅😅😅😅😅😅😅😅😅😅😅😅😅😅😅😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮ㅣ😅😅😮😮😮😮😮😮ㅣ😮😮😮😮😮😮😮😮😅😅😮😅😮😅😅😅😮😮😮😮😮😮😮😮😮😮😮😅😅😅😅😅😮😮😮😮😮😮😮😮😮😮😮😮😅😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😅😮😮😮😮😮😮😮😮😮😮😮😮ㅣ😮😮😮ㅣㅣ😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😅😮😮😅😅😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😅😮😮😮😮😮😮😅😅😅😅😅😅😅😅😮😮😮😮😮😮😮😮😮😮😮ㅑ😮😮😮😮😮😮😅😮😮😮😮😮😮😮😮😮😮😮😅😅😮😮😮😮😅😅😅😅😅😅😅😅😮😮ㅣ😮😮😮ㅣ😮😮ㅣ😮ㅣ😮😮😮😮😮😮😮😮😮😮😮ㅣ😮😮😮😮😮😮😮😮😮😮😮😮😅😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😅😅😅😅😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😅😅😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😮😅😮😅😅😅😅ㅣ😮😮 😮😮😮😮😮😮😮😮😮😮😮😮😮😮😅😮😮😮😮😅😅😅😅😮😮😮😮😮😮😮😅😮😮😮😮😮😮😮😮😮😅😅😮😮😮ㅣ😮
@AhsanAli-vz6mg
@AhsanAli-vz6mg 2 жыл бұрын
Seriously I was waiting for this video Thanks 😊
@GakisStylianos
@GakisStylianos 2 жыл бұрын
Just be careful, think of derivedStateOf just as you would mutableStateOf in a sense that it needs to be remembered! Otherwise this isn't remembered and in case of recomposition will just be called again from scratch. And overall it feels like your explanation on derivedStateOf could be improved a bit. You didn't mention anything about how it implicitly "subscribes" to the state objects that are being accessed in there, but doesn't have any mechanism to update itself when non-state objects are being read in its lambda are changed so it would then show stale data. I really suggest people to read the excellent documentation on these, it does a great job explaining with examples how they work.
@vitorgabrielsilvanasciment5846
@vitorgabrielsilvanasciment5846 4 ай бұрын
Great point here.
@Soulcybering
@Soulcybering 2 жыл бұрын
Thank you for the video. I will watch all the Compose serie 👍
@techmarinar
@techmarinar Жыл бұрын
Gem's channel , thanx man , wish you all the best in your life
@premi_uz
@premi_uz 6 ай бұрын
thanks for all
@x32gx
@x32gx 2 жыл бұрын
Hi Phillipp!! As always, top notch videos! Thank you! I have a question, I have a Composable function that creates a JFreeChart object which basically gets recomposed when ever its DataSet values are updated. But in that case, the entire JFreeChart object gets recreated again and again with each recomposition. So it appears to be a side effect. Is LaunchedEffect the more accurate choice to prevent that? Do I create the JFreeChart object with key1 = true and then simply let it observe its DataSet updates? Thanks!
@slobicak
@slobicak Жыл бұрын
Thanks for sharing, really cool video!
@JamesBond-mq7pd
@JamesBond-mq7pd 2 ай бұрын
wow. such a good explanation.
@skandarsouissi7282
@skandarsouissi7282 Ай бұрын
I def needed this
@t_regbs
@t_regbs 2 жыл бұрын
thank you so much for this
@michaberkowicz8239
@michaberkowicz8239 2 жыл бұрын
Compose related videos always welcome
@mukuljangir9162
@mukuljangir9162 2 жыл бұрын
Philip You are Hero
@original_anu
@original_anu 2 жыл бұрын
Thanks a lot for this ❤️ I'll bookmark it for future reference :P
@koetjape4440
@koetjape4440 Жыл бұрын
Philipp, Hi! I love your content, thank you for that. I don't understand one thing. Could you please explain me ? Why cant we just use derivedStateOf everywhere since it optimizes everything ?
@MetehanBOLAT
@MetehanBOLAT 2 жыл бұрын
You are the few youtube channels that I have turned on notifications on :D You touch on very important points as always. Thanks.
@PhilippLackner
@PhilippLackner 2 жыл бұрын
Thanks man!
@fawazmn_071
@fawazmn_071 2 жыл бұрын
Omg thanks very much ! ✨
@cristianovecchi
@cristianovecchi 2 жыл бұрын
Great! So much useful!
@abdelsttarahmed8821
@abdelsttarahmed8821 2 жыл бұрын
Really Amaizing video , thank you 😎
@user-gi4no6gn7m
@user-gi4no6gn7m 2 жыл бұрын
As always Sir Philipp is here to save the day
@original_anu
@original_anu Жыл бұрын
Months later, my webview was playing audio event after navigating away. Destroying it in DisposableEffect did the trick. Good thing I bookmarked this video 😁
@The-Fuse
@The-Fuse 2 жыл бұрын
Thank you philipp 😁
@PhilippLackner
@PhilippLackner 2 жыл бұрын
You're welcome
@iftak01
@iftak01 22 күн бұрын
Best explanation video of this thanks bias god
@nCodeLab
@nCodeLab 2 жыл бұрын
quality videos after long time ......need more clean architecture full apps tutorial or compose tutorial..(animation ,canvas ,custom modifiers , custom layout..etc)
@bro_chenzox
@bro_chenzox 2 жыл бұрын
Cool episode! Which one of dark themes plugin do you use?
@mustafaammar551
@mustafaammar551 2 жыл бұрын
very cool video thank you bro
@dev_jeongdaeri
@dev_jeongdaeri 2 жыл бұрын
Super awesome!!
@themisterravenous1785
@themisterravenous1785 2 жыл бұрын
awesome video! just one simple thing I notest was he snapshotFlow using the distincUntilChanged(), actually the snapshotFlow itself is already handling it, so it will get the latest value of the state if its value is different, so in this case you dont need call the distinctUntilChanged. btw thanks a lot for this video it helped a lot to understand all of them
@PhilippLackner
@PhilippLackner 2 жыл бұрын
Awesome, thank you!
@abada-s
@abada-s 2 жыл бұрын
Is it good to use derucedStateOf instead of rememberStateOf in all cases?
@mehmetpeker9047
@mehmetpeker9047 2 жыл бұрын
Can you make video about usage of native ad as a up to date and how to use in jetpack compose?
@ShivamVermaokdone
@ShivamVermaokdone 3 ай бұрын
Top channel for genuine content on android after the Google android developer channel.
@ubersticks
@ubersticks 2 жыл бұрын
Hi Philip - excellent again! How about a quickie example explaining delegation ("by") and when to use that. I find it very confusing and maybe you could shine some light on this.
@PhilippLackner
@PhilippLackner 2 жыл бұрын
Thanks for the idea, however right now i have tons of other videos in my pipeline 😄
@duc-fw
@duc-fw Жыл бұрын
is it acceptable to have the key be modified within the LaunchedEffect block?
@user-dn1ep2kb4o
@user-dn1ep2kb4o 2 жыл бұрын
Hey, just finished course about multimoduling. Have a question - when services are needed? For example, if there are any pros for moving api calls to service, if these are periodic calls made with workmanager? Thanks)
@PhilippLackner
@PhilippLackner 2 жыл бұрын
Workmanager is needed when you have work that needs to be done reliably, even when your app is closed or the device restarted. Not for user initiated network calls
@youngtigersivateja
@youngtigersivateja 2 жыл бұрын
In your MVVM News App, how to refresh the news list using swiprefershlayout listener or when call news list api from onresume override method? I am new to MVVM architecture, please help me as i am calling the news list api in onresume but not in oncreate as i need to refresh the news list every time i came back to breakingnews fragment.
@ifedayoadekoya6694
@ifedayoadekoya6694 Жыл бұрын
I’m trying to run a recursive task every 15seconds (like call an api) on my jetpack screen, how can I achieve this with launched effect or any other Android class without using workmanager.
@arthurgichuhi
@arthurgichuhi 6 ай бұрын
This stuff would be much easier with practical uses but great content as always.
@subindsuresh4897
@subindsuresh4897 2 жыл бұрын
Gym Shark should start sponsoring Philipp !!
@mertozankahraman
@mertozankahraman 11 ай бұрын
Adam geldi ADAM
@leonardovalle2763
@leonardovalle2763 2 жыл бұрын
Hi Philipp, awesome video, thanks for the great content! Just a question, how would you implement a snackbar call after navigation? when i perform an action, the app navigates up and need to show a snackbar, but i am just not being able to do it... how would you do it?
@PhilippLackner
@PhilippLackner 2 жыл бұрын
Have it in a launched effect block in the screen you're navigating to if it should always show up or based on some kind of nav parameter
@12Playmobil
@12Playmobil 2 жыл бұрын
What you can also do is have a scope = rememberCoroutineScope and a scaffoldState = rememebreScaffoldState in your App() composable and a Scaffold. Your composables should expect a showSnackbar: (String, SnackbarDuration) -> Unit parameter, that you can call (for example when navigating up) like showSnackbar ("Your snack message", SnackbarDuration.Short). Your navigation composable should expect the same function parameter so you can just pass it on to your actual screen composables when creating the instances. In the end your Scaffold in App can look like this: Scaffold( .. state= scaffoldState .. ) { .. YourNavigationComp( navHost =... showSnackbar = { message, duration -> scope.launch { scaffoldState.showSnackbar(message, duration) } }) } With this solution you have a snackbarScope scoped to the App() so your snackbar is still visible during navigation and in the new screen. (Obviously if you need a snackbar scoped to your screen you can implement the scope and Scaffold there). Hope I could explain it well and could help.
@12Playmobil
@12Playmobil 2 жыл бұрын
Your question inspired me to write an article about about the topic in Medium, because I had this same struggle some time ago. I can not post the link here but added it to my youtube bio.
@tarsilacostalonga
@tarsilacostalonga Жыл бұрын
Hi, Philipp, great video! What is yout Android Studio theme? Thanks =)
@PhilippLackner
@PhilippLackner Жыл бұрын
Xcode dark
@keepgoingman5829
@keepgoingman5829 2 жыл бұрын
Do you live in my head? How do you always know all subscriber's needs? Thank you!
@rollebonmarquis7574
@rollebonmarquis7574 Жыл бұрын
In my opinion, 19:00 is missing the point. produceState() uses LaunchEffect in the background so that's another difference. And basically the example with the flow constructor seems to be breaking the core principles of compose, it seems like it's doing backwards writes, you are going to end up with infinite recompositions. Saying this as someone who is trying to wrap my head around Compose. :D
@karamba6936
@karamba6936 Жыл бұрын
Hello. I saw that people place derivedStateOf inside remember. Is that wrong?Because it cash and not calculate each run
@linmaung
@linmaung 2 жыл бұрын
Love that content...
@PhilippLackner
@PhilippLackner 2 жыл бұрын
Happy it helps!
@petterstenberg617
@petterstenberg617 Жыл бұрын
Thanks for your educational and helpful videos! The Android Studio theme that you’re using looks awsome, what is the name of that? ⭐️🧐 Cheers from Sweden 🍻
@PhilippLackner
@PhilippLackner Жыл бұрын
Thanks, it's xcode dark 🙌
@petterstenberg617
@petterstenberg617 Жыл бұрын
@@PhilippLackner Thank you very much! 🙏
@user-sb5ud7ek9c
@user-sb5ud7ek9c Жыл бұрын
what's the hotkey that you use at 15:28 to move the line up, through a brace, into onDispose scope?
@user-sb5ud7ek9c
@user-sb5ud7ek9c Жыл бұрын
oh, its shift+alt+up / down. looked it up
@akshaytyagi9791
@akshaytyagi9791 Жыл бұрын
at 3:00 you said its a terrible practise to directly call api inside composable. Can you please tell what is the best practise ?
@slobicak
@slobicak Жыл бұрын
Call it from a viewmodel / use case / repository
@brigadir5830
@brigadir5830 Жыл бұрын
Привет из России. Спасибо за понятные и хорошие уроки это лучшие курсы для начинающих💗💗💗
@be_like__prateek
@be_like__prateek 2 жыл бұрын
Respect++ 🔥🚀
@ravi_sorathiya
@ravi_sorathiya 2 жыл бұрын
What's the name of your android studio theme? Philip
@PhilippLackner
@PhilippLackner 2 жыл бұрын
Xcode dark
@yonghunchoi8944
@yonghunchoi8944 2 жыл бұрын
형 너무 사랑해❤️❤️
@azatnabiullin2263
@azatnabiullin2263 7 ай бұрын
On 7:02 you said that code in LaunchedEffect only once when screen composed for the first time. How another Event can happen in this case? E.g. it collects first event - ShowSnackbar and then Navigate event happens but you told that code executed only once
@PhilippLackner
@PhilippLackner 7 ай бұрын
The launch effect block is executed once, so it subscribes to the flow once. But once a subscription is established the collect block will trigger with each event
@azatnabiullin2263
@azatnabiullin2263 7 ай бұрын
@@PhilippLackner thank you
@teeesen
@teeesen 6 ай бұрын
@PhilippLackner In the LaunchedEffectAnimation example. How can `counter` change? It’s just an Int parameter and is never assigned to. Would the example work the same if the first argument to LaunchedEffect were `true`? Great videos, by the way; I’m working my way through the original Compose series and have learned a lot.
@blockchaindevelopment120
@blockchaindevelopment120 2 жыл бұрын
Sir Complete jetpack compose course.
@Daaaaaaavid
@Daaaaaaavid 11 ай бұрын
I find scopes a really hard concept to get.
@marvelrivera1194
@marvelrivera1194 Жыл бұрын
Cool
@micahspecial5927
@micahspecial5927 9 ай бұрын
Im stuck with EffectHandlersTheme not detect
@xCrawfly
@xCrawfly 2 ай бұрын
So was I, but you can usually get the answers in the comments. This is a response from @tetsuoshiva: When you create a new Compose project, it creates a theme named "[ProjectName]Theme". Chances are the project was named "EffectHandlers", and "EffectHandlersTheme" is the theme that was created at project creation. Just write your project name instead of "EffectHandlers", followed by "Theme".
@pfrost982yt
@pfrost982yt Жыл бұрын
Not clear without examples
@gofudgeyourselves9024
@gofudgeyourselves9024 2 жыл бұрын
Thank you re baba Thank you
@PhilippLackner
@PhilippLackner 2 жыл бұрын
Always welcome
@vladalexeev8529
@vladalexeev8529 4 ай бұрын
I'm so stupid, I still can't grasp what is it
@lingviston
@lingviston Жыл бұрын
Sadly, all `SideEffect` examples strive to be so oversimplified, that neither of them actually demonstrates the real use case of it. Like: what would happen if you do this call without wrapping in `SideEffect`? This effect handler deserves better example.
@likatest7718
@likatest7718 7 ай бұрын
Just example, therw is no practice :(
@testg4andmmm129
@testg4andmmm129 Жыл бұрын
This side effect makes me think twice whet i should use this or maui csharpmarkup. Compose makes it so much complicated especially in example. Why not make normal oop. İnstead of frp in order to conpansate for downside of functional programming, they added remember state etc. How to cover a hole with another thing that also has a hole. Total bullshit..
@tetsuoshiva
@tetsuoshiva Жыл бұрын
Wait, you never explained what EffectHandlersTheme is.
@ArthurRousseau2
@ArthurRousseau2 Жыл бұрын
When you create a new Compose project, it creates a theme named "[ProjectName]Theme". Chances are the project was named "EffectHandlers", and "EffectHandlersTheme" is the theme that was created at project creation.
@AnhBaGopDon
@AnhBaGopDon 3 ай бұрын
@@ArthurRousseau2 It has me stumped for an hour searching google, thank alot man.
@xCrawfly
@xCrawfly 2 ай бұрын
@@ArthurRousseau2 Thanks! I started to come to the comments before googling stuff and I'm so happy for that.
@gilbartodepiento7584
@gilbartodepiento7584 7 ай бұрын
Until video 9 in this playlist, I was more or less understanding the concept. After watching this one, I feel like I have totally lost the plot
@pavlopavlov5169
@pavlopavlov5169 8 ай бұрын
Very cool lessons, please add Ukrainian subtitles.
@martinstreif2879
@martinstreif2879 2 жыл бұрын
At 23:44 I noticed you're german
@rabaka7899
@rabaka7899 2 жыл бұрын
@Alexandr234
@Alexandr234 8 ай бұрын
nice rewriting google guides
Simple Animations - Android Jetpack Compose - Part 11
13:42
Philipp Lackner
Рет қаралды 38 М.
5 Fatal Coroutine Mistakes Nobody Tells You About
18:15
Philipp Lackner
Рет қаралды 85 М.
Did you believe it was real? #tiktok
00:25
Анастасия Тарасова
Рет қаралды 38 МЛН
아이스크림으로 체감되는 요즘 물가
00:16
진영민yeongmin
Рет қаралды 4 МЛН
МАМА И STANDOFF 2 😳 !FAKE GUN! #shorts
00:34
INNA SERG
Рет қаралды 4,4 МЛН
100+ Linux Things you Need to Know
12:23
Fireship
Рет қаралды 60 М.
Advanced state and side effects in Jetpack Compose
41:21
Android Developers
Рет қаралды 32 М.
THIS Compose-State Mistake Leads to Problems In Your Code
7:58
Philipp Lackner
Рет қаралды 38 М.
Should You Use Compose State or StateFlow in Your ViewModels?
13:59
Philipp Lackner
Рет қаралды 71 М.
Performance Optimization with @Stable and @Immutable in Jetpack Compose
16:47
Clean Theming in Compose (You're Doing It Wrong!)
10:43
Philipp Lackner
Рет қаралды 39 М.
Gestures in Jetpack Compose
31:33
Android Developers
Рет қаралды 21 М.
A Complete .NET Developer's Guide to Span with Stephen Toub
1:02:48
Did you believe it was real? #tiktok
00:25
Анастасия Тарасова
Рет қаралды 38 МЛН