साइड-इफ़ेक्ट, ऐप्लिकेशन की स्थिति में होने वाला ऐसा बदलाव है जो कंपोज़ेबल फ़ंक्शन के दायरे से बाहर होता है. कंपोज़ेबल की लाइफ़साइकल और प्रॉपर्टी की वजह से, कंपोज़ेबल का कोई खराब असर नहीं होना चाहिए. जैसे, रीकंपोज़िशन का अनुमान न लगाया जा सके, कंपोज़ेबल के रीकंपोज़िशन को अलग-अलग क्रम में लागू किया जा सके या रीकंपोज़िशन को खारिज किया जा सके.
हालांकि, कभी-कभी खराब असर ज़रूरी होते हैं. उदाहरण के लिए, किसी एक इवेंट को ट्रिगर करने के लिए, जैसे कि स्नैकबार दिखाना या किसी खास स्थिति के आधार पर दूसरी स्क्रीन पर जाना. इन कार्रवाइयों को ऐसे कंट्रोल किए गए एनवायरमेंट से कॉल किया जाना चाहिए जो कंपोज़ेबल की लाइफ़साइकल के बारे में जानता हो. इस पेज पर, आपको Jetpack Compose में उपलब्ध अलग-अलग साइड-इफ़ेक्ट एपीआई के बारे में जानकारी मिलेगी.
स्टेट और इफ़ेक्ट के इस्तेमाल के उदाहरण
Compose में सोचने के दस्तावेज़ में बताया गया है कि कंपोज़ेबल का कोई खराब असर नहीं होना चाहिए. जब आपको ऐप्लिकेशन की स्थिति में बदलाव करने की ज़रूरत हो, तो आपको Effect API का इस्तेमाल करना चाहिए, ताकि उन साइड इफ़ेक्ट को अनुमानित तरीके से लागू किया जा सके. इसके बारे में, स्टेट मैनेज करने से जुड़े दस्तावेज़ में बताया गया है.
Compose में इफ़ेक्ट इस्तेमाल करने के कई तरीके हैं. इसलिए, इनका ज़रूरत से ज़्यादा इस्तेमाल किया जा सकता है. पक्का करें कि उनमें किया जाने वाला काम यूज़र इंटरफ़ेस (यूआई) से जुड़ा हो और एक ही दिशा में डेटा फ़्लो को न तोड़े. इसके बारे में स्टेट मैनेज करने से जुड़े दस्तावेज़ में बताया गया है.
LaunchedEffect: कंपोज़ेबल के स्कोप में, सस्पेंड फ़ंक्शन चलाएं
किसी कंपोज़ेबल के लाइफ़साइकल के दौरान काम करने और सस्पेंड फ़ंक्शन को कॉल करने के लिए, LaunchedEffect कंपोज़ेबल का इस्तेमाल करें. जब LaunchedEffect कंपोज़िशन में शामिल होता है, तो यह पैरामीटर के तौर पर पास किए गए कोड ब्लॉक के साथ एक कोरूटीन लॉन्च करता है. अगर LaunchedEffect कंपोज़िशन से बाहर निकल जाता है, तो कोरूटीन रद्द हो जाएगा. अगर LaunchedEffect को अलग-अलग कुंजियों के साथ फिर से कंपोज़ किया जाता है, तो मौजूदा कोरूटीन रद्द हो जाएगा और नया सस्पेंड फ़ंक्शन नए कोरूटीन में लॉन्च हो जाएगा. इसके बारे में ज़्यादा जानने के लिए, नीचे दिया गया इफ़ेक्ट फिर से शुरू करना सेक्शन देखें.
उदाहरण के लिए, यहां एक ऐनिमेशन दिया गया है जो कॉन्फ़िगर की जा सकने वाली देरी के साथ, ऐल्फ़ा वैल्यू को पल्स करता है:
// Allow the pulse rate to be configured, so it can be sped up if the user is running // out of time var pulseRateMs by remember { mutableLongStateOf(3000L) } val alpha = remember { Animatable(1f) } LaunchedEffect(pulseRateMs) { // Restart the effect when the pulse rate changes while (isActive) { delay(pulseRateMs) // Pulse the alpha every pulseRateMs to alert the user alpha.animateTo(0f) alpha.animateTo(1f) } }
ऊपर दिए गए कोड में, ऐनिमेशन में सस्पेंड करने वाले फ़ंक्शन
delay
का इस्तेमाल किया गया है, ताकि सेट किए गए समय तक इंतज़ार किया जा सके. इसके बाद, यह animateTo का इस्तेमाल करके,
अल्फ़ा को क्रम से शून्य पर और फिर से वापस ऐनिमेट करता है.
यह प्रोसेस, कंपोज़ेबल के लाइफ़साइकल के दौरान दोहराई जाएगी.
rememberCoroutineScope: कंपोज़ेबल के बाहर कोरूटीन लॉन्च करने के लिए, कंपोज़िशन-अवेयर स्कोप पाना
LaunchedEffect, ऐप्लिकेशन बनाने की सुविधा है. इसलिए, इसका इस्तेमाल सिर्फ़ ऐप्लिकेशन बनाने की अन्य सुविधाओं में किया जा सकता है. किसी कंपोज़ेबल के बाहर कोरूटीन लॉन्च करने के लिए,
लेकिन स्कोप किया गया है, ताकि कंपोज़िशन से बाहर निकलने पर यह अपने-आप रद्द हो जाए,
rememberCoroutineScope का इस्तेमाल करें.
जब भी आपको एक या उससे ज़्यादा कोरूटीन की लाइफ़साइकल को मैन्युअल तरीके से कंट्रोल करना हो, तब भी rememberCoroutineScope का इस्तेमाल करें. उदाहरण के लिए, कोई उपयोगकर्ता इवेंट होने पर ऐनिमेशन रद्द करना.
rememberCoroutineScope एक ऐसा composable फ़ंक्शन है जो कंपोज़िशन के उस पॉइंट से जुड़ा CoroutineScope दिखाता है जहां इसे कॉल किया जाता है. कॉल के कंपोज़िशन से बाहर निकलने पर, स्कोप रद्द हो जाएगा.
पिछले उदाहरण के मुताबिक, इस कोड का इस्तेमाल करके Snackbar को तब दिखाया जा सकता है, जब उपयोगकर्ता Button पर टैप करे:
@Composable fun MoviesScreen(snackbarHostState: SnackbarHostState) { // Creates a CoroutineScope bound to the MoviesScreen's lifecycle val scope = rememberCoroutineScope() Scaffold( snackbarHost = { SnackbarHost(hostState = snackbarHostState) } ) { contentPadding -> Column(Modifier.padding(contentPadding)) { Button( onClick = { // Create a new coroutine in the event handler to show a snackbar scope.launch { snackbarHostState.showSnackbar("Something happened!") } } ) { Text("Press me") } } } }
rememberUpdatedState: किसी इफ़ेक्ट में ऐसी वैल्यू को रेफ़रंस के तौर पर इस्तेमाल करना जिसे वैल्यू बदलने पर रीस्टार्ट नहीं किया जाना चाहिए
किसी मुख्य पैरामीटर में बदलाव होने पर, LaunchedEffect फिर से शुरू हो जाता है. हालांकि, कुछ मामलों में ऐसा हो सकता है कि आपको अपने इफ़ेक्ट में कोई ऐसी वैल्यू कैप्चर करनी हो जिसके बदलने पर, आपको इफ़ेक्ट को रीस्टार्ट न करना पड़े. ऐसा करने के लिए, rememberUpdatedState का इस्तेमाल करके इस वैल्यू का रेफ़रंस बनाना ज़रूरी है. इस रेफ़रंस को कैप्चर और अपडेट किया जा सकता है. यह तरीका उन इफ़ेक्ट के लिए मददगार होता है जिनमें लंबे समय तक चलने वाले ऑपरेशन शामिल होते हैं. इन ऑपरेशन को फिर से बनाना और रीस्टार्ट करना महंगा या मुश्किल हो सकता है.
उदाहरण के लिए, मान लें कि आपके ऐप्लिकेशन में एक LandingScreen है, जो कुछ समय बाद गायब हो जाता है. अगर LandingScreen को फिर से कंपोज़ किया जाता है, तो भी कुछ समय तक इंतज़ार करने और समय बीत जाने की सूचना देने वाले इफ़ेक्ट को रीस्टार्ट नहीं किया जाना चाहिए:
@Composable fun LandingScreen(onTimeout: () -> Unit) { // This will always refer to the latest onTimeout function that // LandingScreen was recomposed with val currentOnTimeout by rememberUpdatedState(onTimeout) // Create an effect that matches the lifecycle of LandingScreen. // If LandingScreen recomposes, the delay shouldn't start again. LaunchedEffect(true) { delay(SplashWaitTimeMillis) currentOnTimeout() } /* Landing screen content */ }
कॉल साइट की लाइफ़साइकल से मैच करने वाला इफ़ेक्ट बनाने के लिए, Unit या true जैसे कभी न बदलने वाले कॉन्स्टेंट को पैरामीटर के तौर पर पास किया जाता है. ऊपर दिए गए कोड में, LaunchedEffect(true) का इस्तेमाल किया गया है. यह पक्का करने के लिए कि onTimeout लैम्डा में हमेशा वह नई वैल्यू मौजूद हो जिसके साथ LandingScreen को फिर से कंपोज़ किया गया था, onTimeout को rememberUpdatedState फ़ंक्शन के साथ रैप करना होगा.
कोड में दिखाए गए State, currentOnTimeout का इस्तेमाल, इफ़ेक्ट में किया जाना चाहिए.
DisposableEffect: ऐसे इफ़ेक्ट जिन्हें क्लीनअप की ज़रूरत है
अगर कुंजियों में बदलाव होने के बाद, खराब असर को साफ़ करना ज़रूरी है या कंपोज़ेबल, कंपोज़िशन को छोड़ देता है, तो DisposableEffect का इस्तेमाल करें.
अगर DisposableEffect कुंजियां बदलती हैं, तो कंपोज़ेबल को अपने मौजूदा इफ़ेक्ट को हटाना (क्लीनअप करना) होगा. साथ ही, इफ़ेक्ट को फिर से कॉल करके रीसेट करना होगा.
उदाहरण के लिए, हो सकता है कि आपको
LifecycleObserver
का इस्तेमाल करके,
Lifecycle इवेंट
के आधार पर Analytics इवेंट भेजने हों.
Compose में उन इवेंट को सुनने के लिए, DisposableEffect का इस्तेमाल करें. इससे, ज़रूरत पड़ने पर ऑब्ज़र्वर को रजिस्टर और अनरजिस्टर किया जा सकता है.
@Composable fun HomeScreen( lifecycleOwner: LifecycleOwner = LocalLifecycleOwner.current, onStart: () -> Unit, // Send the 'started' analytics event onStop: () -> Unit // Send the 'stopped' analytics event ) { // Safely update the current lambdas when a new one is provided val currentOnStart by rememberUpdatedState(onStart) val currentOnStop by rememberUpdatedState(onStop) // If `lifecycleOwner` changes, dispose and reset the effect DisposableEffect(lifecycleOwner) { // Create an observer that triggers our remembered callbacks // for sending analytics events val observer = LifecycleEventObserver { _, event -> if (event == Lifecycle.Event.ON_START) { currentOnStart() } else if (event == Lifecycle.Event.ON_STOP) { currentOnStop() } } // Add the observer to the lifecycle lifecycleOwner.lifecycle.addObserver(observer) // When the effect leaves the Composition, remove the observer onDispose { lifecycleOwner.lifecycle.removeObserver(observer) } } /* Home screen content */ }
ऊपर दिए गए कोड में, इफ़ेक्ट observer को lifecycleOwner में जोड़ देगा. अगर lifecycleOwner में बदलाव होता है, तो इफ़ेक्ट को हटा दिया जाता है और नए lifecycleOwner के साथ रीस्टार्ट किया जाता है.
DisposableEffect के कोड ब्लॉक में, आखिरी स्टेटमेंट के तौर पर onDispose क्लॉज़ शामिल होना चाहिए. ऐसा न होने पर, IDE में बिल्ड-टाइम वाली गड़बड़ी दिखती है.
SideEffect: Compose स्टेट को नॉन-Compose कोड में पब्लिश करना
Compose की स्थिति को उन ऑब्जेक्ट के साथ शेयर करने के लिए जिन्हें Compose मैनेज नहीं करता है, SideEffect
कंपोज़ेबल का इस्तेमाल करें. SideEffect का इस्तेमाल करने से यह गारंटी मिलती है कि हर बार रीकंपोज़िशन पूरा होने के बाद, इफ़ेक्ट लागू होगा. दूसरी ओर, रीकंपोज़िशन के पूरा होने से पहले कोई इफ़ेक्ट लागू करना गलत है. ऐसा तब होता है, जब इफ़ेक्ट को सीधे कंपोज़ेबल में लिखा जाता है.
उदाहरण के लिए, आपकी Analytics लाइब्रेरी आपको अपने उपयोगकर्ताओं को सेगमेंट में बांटने की अनुमति दे सकती है. इसके लिए, आपको बाद के सभी Analytics इवेंट में कस्टम मेटाडेटा ("उपयोगकर्ता प्रॉपर्टी" इस उदाहरण में) अटैच करना होगा. अपनी Analytics लाइब्रेरी को मौजूदा उपयोगकर्ता के टाइप की जानकारी देने के लिए, SideEffect का इस्तेमाल करके उसकी वैल्यू अपडेट करें.
@Composable fun rememberFirebaseAnalytics(user: User): FirebaseAnalytics { val analytics: FirebaseAnalytics = remember { FirebaseAnalytics() } // On every successful composition, update FirebaseAnalytics with // the userType from the current User, ensuring that future analytics // events have this metadata attached SideEffect { analytics.setUserProperty("userType", user.userType) } return analytics }
produceState: नॉन-Compose स्टेट को Compose स्टेट में बदलना
produceState
कंपोज़िशन के दायरे में आने वाले कोरूटीन को लॉन्च करता है. यह कोरूटीन, वैल्यू को रिटर्न किए गए State में पुश कर सकता है. इसका इस्तेमाल, नॉन-Compose स्टेट को Compose स्टेट में बदलने के लिए करें. उदाहरण के लिए, सदस्यता पर आधारित बाहरी स्टेट, जैसे कि Flow, LiveData या RxJava को कंपोज़िशन में शामिल करना.
जब produceState कंपोज़िशन में शामिल होता है, तब प्रोड्यूसर लॉन्च होता है. कंपोज़िशन से बाहर निकलने पर, इसे रद्द कर दिया जाएगा. वापस किया गया State कॉन्फ़्लेट;
एक ही वैल्यू सेट करने से, फिर से कंपोज़िशन ट्रिगर नहीं होगा.
भले ही, produceState एक कोरूटीन बनाता है, लेकिन इसका इस्तेमाल डेटा के ऐसे सोर्स को मॉनिटर करने के लिए भी किया जा सकता है जो निलंबित नहीं होते. उस सोर्स की सदस्यता हटाने के लिए, awaitDispose
फ़ंक्शन का इस्तेमाल करें.
यहां दिए गए उदाहरण में, नेटवर्क से इमेज लोड करने के लिए produceState का इस्तेमाल करने का तरीका बताया गया है. loadNetworkImage कंपोज़ेबल फ़ंक्शन, State दिखाता है. इसका इस्तेमाल अन्य कंपोज़ेबल में किया जा सकता है.
@Composable fun loadNetworkImage( url: String, imageRepository: ImageRepository = ImageRepository() ): State<Result<Image>> { // Creates a State<T> with Result.Loading as initial value // If either `url` or `imageRepository` changes, the running producer // will cancel and will be re-launched with the new inputs. return produceState<Result<Image>>(initialValue = Result.Loading, url, imageRepository) { // In a coroutine, can make suspend calls val image = imageRepository.load(url) // Update State with either an Error or Success result. // This will trigger a recomposition where this State is read value = if (image == null) { Result.Error } else { Result.Success(image) } } }
derivedStateOf: एक या एक से ज़्यादा स्टेट ऑब्जेक्ट को दूसरी स्टेट में बदलना
Compose में, जब भी मॉनिटर किए गए स्टेट ऑब्जेक्ट या कंपोज़ेबल इनपुट में बदलाव होता है, तो रीकंपोज़िशन होता है. ऐसा हो सकता है कि यूज़र इंटरफ़ेस (यूआई) को अपडेट करने की ज़रूरत के मुकाबले, कोई स्टेट ऑब्जेक्ट या इनपुट ज़्यादा बार बदल रहा हो. इससे, यूज़र इंटरफ़ेस (यूआई) को बार-बार रीकंपोज़ करना पड़ता है.
derivedStateOf फ़ंक्शन का इस्तेमाल तब करना चाहिए, जब कंपोज़ेबल में आपके इनपुट, फिर से कंपोज़ करने की ज़रूरत से ज़्यादा बार बदल रहे हों. ऐसा अक्सर तब होता है, जब कोई चीज़ बार-बार बदल रही हो, जैसे कि स्क्रोल की पोज़िशन. हालांकि, कंपोज़ेबल को सिर्फ़ तब प्रतिक्रिया देनी होती है, जब वह किसी तय थ्रेशोल्ड को पार कर लेता है. derivedStateOf, एक नया Compose स्टेट ऑब्जेक्ट बनाता है.
इसे देखा जा सकता है कि यह सिर्फ़ उतना ही अपडेट होता है जितना आपको चाहिए. इस तरह, यह Kotlin Flow के distinctUntilChanged() ऑपरेटर की तरह काम करता है.
सही इस्तेमाल
यहां दिए गए स्निपेट में, derivedStateOf के इस्तेमाल का सही उदाहरण दिखाया गया है:
@Composable // When the messages parameter changes, the MessageList // composable recomposes. derivedStateOf does not // affect this recomposition. fun MessageList(messages: List<Message>) { Box { val listState = rememberLazyListState() LazyColumn(state = listState) { // ... } // Show the button if the first visible item is past // the first item. We use a remembered derived state to // minimize unnecessary compositions val showButton by remember { derivedStateOf { listState.firstVisibleItemIndex > 0 } } AnimatedVisibility(visible = showButton) { ScrollToTopButton() } } }
इस स्निपेट में, firstVisibleItemIndex की वैल्यू तब बदलती है, जब दिखने वाले पहले आइटम में बदलाव होता है. स्क्रोल करने पर, वैल्यू 0, 1, 2, 3, 4, 5 वगैरह हो जाती है.
हालांकि, रीकंपोज़िशन सिर्फ़ तब होना चाहिए, जब वैल्यू 0 से ज़्यादा हो.
अपडेट के अंतराल में इस अंतर का मतलब है कि यह derivedStateOf के लिए इस्तेमाल का एक अच्छा उदाहरण है.
गलत इस्तेमाल
आम तौर पर, यह गलती की जाती है कि दो Compose स्टेट ऑब्जेक्ट को जोड़ते समय, derivedStateOf का इस्तेमाल किया जाना चाहिए, क्योंकि "स्टेट को डिराइव" किया जा रहा है. हालांकि, यह पूरी तरह से ओवरहेड है और इसकी ज़रूरत नहीं है, जैसा कि इस स्निपेट में दिखाया गया है:
// DO NOT USE. Incorrect usage of derivedStateOf. var firstName by remember { mutableStateOf("") } var lastName by remember { mutableStateOf("") } val fullNameBad by remember { derivedStateOf { "$firstName $lastName" } } // This is bad!!! val fullNameCorrect = "$firstName $lastName" // This is correct
इस स्निपेट में, fullName को firstName और lastName की तरह ही अपडेट करना होगा. इसलिए, ज़रूरत से ज़्यादा रीकंपोज़िशन नहीं हो रहा है और derivedStateOf का इस्तेमाल करना ज़रूरी नहीं है.
snapshotFlow: Compose के स्टेट को फ़्लो में बदलना
State<T> ऑब्जेक्ट को कोल्ड फ़्लो में बदलने के लिए, snapshotFlow का इस्तेमाल करें. snapshotFlow, इकट्ठा किए जाने पर अपना ब्लॉक चलाता है और इसमें पढ़े गए State ऑब्जेक्ट का नतीजा दिखाता है. जब snapshotFlow ब्लॉक में रीड किए गए State ऑब्जेक्ट में से कोई एक ऑब्जेक्ट बदलता है, तो फ़्लो अपने कलेक्टर को नई वैल्यू भेजता है. ऐसा तब होता है, जब नई वैल्यू, पहले भेजी गई वैल्यू के बराबर न हो. यह व्यवहार Flow.distinctUntilChanged जैसा ही है.
यहां दिए गए उदाहरण में एक साइड इफ़ेक्ट दिखाया गया है. इसमें उपयोगकर्ता के सूची में मौजूद पहले आइटम को स्क्रोल करने पर, Analytics को रिकॉर्ड किया जाता है:
val listState = rememberLazyListState() LazyColumn(state = listState) { // ... } LaunchedEffect(listState) { snapshotFlow { listState.firstVisibleItemIndex } .map { index -> index > 0 } .distinctUntilChanged() .filter { it == true } .collect { MyAnalyticsService.sendScrolledPastFirstItemEvent() } }
ऊपर दिए गए कोड में, listState.firstVisibleItemIndex को एक फ़्लो में बदला गया है. इससे फ़्लो के ऑपरेटर की मदद से फ़ायदा मिल सकता है.
इफ़ेक्ट फिर से चालू किए जा रहे हैं
Compose में कुछ इफ़ेक्ट, जैसे कि LaunchedEffect, produceState या DisposableEffect, अलग-अलग संख्या में आर्ग्युमेंट लेते हैं. ये आर्ग्युमेंट, ऐसी कुंजियां होती हैं जिनका इस्तेमाल, चल रहे इफ़ेक्ट को रद्द करने और नई कुंजियों के साथ नया इफ़ेक्ट शुरू करने के लिए किया जाता है.
इन एपीआई का सामान्य फ़ॉर्मैट यह है:
EffectName(restartIfThisKeyChanges, orThisKey, orThisKey, ...) { block }
इस व्यवहार की बारीकियों की वजह से, समस्याएं तब हो सकती हैं, जब इफ़ेक्ट को रीस्टार्ट करने के लिए इस्तेमाल किए गए पैरामीटर सही न हों:
- इफ़ेक्ट को ज़रूरत से कम बार रीस्टार्ट करने से, आपके ऐप्लिकेशन में गड़बड़ियां हो सकती हैं.
- इफ़ेक्ट को ज़रूरत से ज़्यादा बार रीस्टार्ट करने से, परफ़ॉर्मेंस पर असर पड़ सकता है.
एक सामान्य नियम के तौर पर, कोड के इफ़ेक्ट ब्लॉक में इस्तेमाल किए गए म्यूटेबल और इम्यूटेबल वैरिएबल को इफ़ेक्ट कंपोज़ेबल में पैरामीटर के तौर पर जोड़ा जाना चाहिए. इनके अलावा, इफ़ेक्ट को फिर से शुरू करने के लिए और पैरामीटर जोड़े जा सकते हैं. अगर किसी वैरिएबल में बदलाव होने पर इफ़ेक्ट को रीस्टार्ट नहीं करना है, तो वैरिएबल को rememberUpdatedState में रैप करना चाहिए. अगर वैरिएबल कभी नहीं बदलता, क्योंकि उसे बिना किसी कुंजी के remember में रैप किया गया है, तो आपको वैरिएबल को इफ़ेक्ट के लिए कुंजी के तौर पर पास करने की ज़रूरत नहीं है.
ऊपर दिए गए DisposableEffect कोड में, इफ़ेक्ट अपने ब्लॉक में इस्तेमाल किए गए lifecycleOwner को पैरामीटर के तौर पर लेता है. ऐसा इसलिए, क्योंकि उनमें कोई भी बदलाव होने पर, इफ़ेक्ट को फिर से शुरू करना पड़ता है.
@Composable fun HomeScreen( lifecycleOwner: LifecycleOwner = LocalLifecycleOwner.current, onStart: () -> Unit, // Send the 'started' analytics event onStop: () -> Unit // Send the 'stopped' analytics event ) { // These values never change in Composition val currentOnStart by rememberUpdatedState(onStart) val currentOnStop by rememberUpdatedState(onStop) DisposableEffect(lifecycleOwner) { val observer = LifecycleEventObserver { _, event -> /* ... */ } lifecycleOwner.lifecycle.addObserver(observer) onDispose { lifecycleOwner.lifecycle.removeObserver(observer) } } }
currentOnStart और currentOnStop को DisposableEffect कुंजियों के तौर पर इस्तेमाल करने की ज़रूरत नहीं है. ऐसा इसलिए, क्योंकि rememberUpdatedState का इस्तेमाल करने की वजह से, कंपोज़िशन में इनकी वैल्यू कभी नहीं बदलतीं. अगर lifecycleOwner को पैरामीटर के तौर पर पास नहीं किया जाता है और इसमें बदलाव होता है, तो HomeScreen फिर से कॉम्पोज़ होता है. हालांकि, DisposableEffect को न तो हटाया जाता है और न ही रीस्टार्ट किया जाता है. इससे समस्याएं होती हैं, क्योंकि उस समय से गलत lifecycleOwner का इस्तेमाल किया जाता है.
कुंजी के तौर पर कॉन्सटेंट
इफ़ेक्ट की के तौर पर, true जैसे कॉन्स्टेंट का इस्तेमाल किया जा सकता है, ताकि यह कॉल साइट की लाइफ़साइकल को फ़ॉलो करे. इसके इस्तेमाल के कई सही उदाहरण हैं, जैसे कि ऊपर दिखाया गया LaunchedEffect का उदाहरण. हालांकि, ऐसा करने से पहले,
अच्छी तरह सोच लें और पक्का करें कि आपको यही करना है.
आपके लिए सुझाव
- ध्यान दें: JavaScript बंद होने पर, लिंक टेक्स्ट दिखता है
- स्टेट और Jetpack Compose
- Jetpack Compose के लिए Kotlin
- Compose में व्यू इस्तेमाल करना