साइड-इफ़ेक्ट, ऐप्लिकेशन की स्थिति में होने वाले बदलाव होता है. यह बदलाव, कंपोज़ेबल फ़ंक्शन का स्कोप. कंपोज़ेबल की वजह से लाइफ़साइकल और प्रॉपर्टी, जैसे कि अनुमान नहीं लगाया जा सकता कंपोज़ेबल को फिर से कंपोज़िशन बनाकर, अलग-अलग क्रम में लगाकर या ऐसे रीकंपोज़िशन जिन्हें खारिज किया जा सकता है, लेकिन कंपोज़ेबल का असर खराब होना चाहिए मुफ़्त है.
हालांकि, कभी-कभी खराब असर डालने की ज़रूरत होती है. उदाहरण के लिए, किसी एक नतीजे को लागू करने के लिए जैसे कि स्नैकबार दिखाने या किसी अन्य स्क्रीन पर जाने के लिए, जैसे कि स्थिति. इन कार्रवाइयों को कंट्रोल विंडो से कॉल किया जाना चाहिए ऐसा एनवायरमेंट जो कंपोज़ेबल के लाइफ़साइकल के बारे में जानकारी रखता है. इस पेज पर, इससे आपको Jetpack Compose के अलग-अलग साइड-इफ़ेक्ट एपीआई के बारे में जानकारी मिलेगी.
स्थिति और असर के इस्तेमाल के उदाहरण
जैसा कि Thinking in Compose में बताया गया है दस्तावेज़ के अलावा, कंपोज़ेबल का कोई भी साइड-इफ़ेक्ट नहीं होना चाहिए. आपको कब ऐप्लिकेशन की स्थिति में होने वाले बदलाव (जैसा कि स्टेट दस्तावेज़ दस्तावेज़), आपको इस इफ़ेक्ट का इस्तेमाल करना चाहिए एपीआई, ताकि उन खराब असर का अनुमान सही तरीके से लगाया जा सके.
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 { mutableStateOf(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
एक कंपोज़ेबल फ़ंक्शन है, जो
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
कुंजियां बदलती हैं, तो कंपोज़ेबल को डिसपोज़ करना होगा (ऐसा करें
के लिए क्लीनअप) और उसे रीसेट करने के लिए इफ़ेक्ट को दोबारा कॉल करें.
उदाहरण के लिए, हो सकता है कि आप इसके आधार पर Analytics इवेंट भेजना चाहें
Lifecycle
इवेंट
और पासवर्ड का इस्तेमाल करके
LifecycleObserver
.
उन इवेंट को 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
: लिखें स्थिति को गैर-लिखें कोड में प्रकाशित करें
जिन ऑब्जेक्ट को 'लिखें' विंडो में मैनेज नहीं किया जाता उनके साथ कंपोज़ की स्थिति को शेयर करने के लिए,
SideEffect
कंपोज़ेबल. SideEffect
का इस्तेमाल करने से यह पक्का हो जाता है कि इफ़ेक्ट लागू होने के बाद
उसे रीकॉम्पोनेंट किया जा सकता है. दूसरी ओर, यह गलत है
एक सफल रीकंपोज़िशन की गारंटी मिलने से पहले एक प्रभाव करना होगा, जो कि
केस को सीधे किसी कंपोज़ेबल में लिखने से पहले उसे इस्तेमाल करें.
उदाहरण के लिए, आंकड़ों की लाइब्रेरी आपको अपने उपयोगकर्ता को
कस्टम मेटाडेटा (इस उदाहरण में "उपयोगकर्ता प्रॉपर्टी") अटैच करके जनसंख्या
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
: गैर-लिखें स्थिति को लिखें स्थिति में बदलें
produceState
कंपोज़िशन के लिए एक कोरूटीन स्कोप लॉन्च करता है, जो वैल्यू को
State
लौटाया गया. इसका इस्तेमाल इन कामों के लिए करें
गैर-लिखें स्थिति को लिखें स्थिति में बदलें, उदाहरण के लिए बाहरी
सदस्यता-आधारित स्थिति जैसे कि 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
: एक या एक से ज़्यादा स्थिति वाले ऑब्जेक्ट को दूसरी स्थिति में बदलें
लिखने के दौरान, बदलाव होता है हर बार मॉनिटर किए जा सकने वाले स्टेट ऑब्जेक्ट या कंपोज़ेबल इनपुट में बदलाव होने पर. स्टेट ऑब्जेक्ट हो सकता है कि यूज़र इंटरफ़ेस (यूआई) को अपडेट करने की ज़रूरत से ज़्यादा बार इनपुट बदल रहा हो, इसकी वजह से, उसे फिर से बनाने में दिक्कत आ रही है.
आपको derivedStateOf
का इस्तेमाल करना चाहिए
जब कंपोज़ेबल में आपके इनपुट ज़रूरत से ज़्यादा बदल रहे हों
उसे रीकंपोज़ करने के लिए. ऐसा अक्सर तब होता है, जब कोई चीज़ अक्सर बदलती रहती है, जैसे कि
स्क्रोल की पोज़िशन पर दिखते हैं, लेकिन कंपोज़ेबल को रिएक्शन करने के बाद ही उस पर प्रतिक्रिया देने की ज़रूरत होती है
तय सीमा तक. derivedStateOf
, नए तरीके से लिखने के लिए स्टेट ऑब्जेक्ट बनाता है
देख सकते हैं कि आपकी ज़रूरत के हिसाब से अपडेट मिलते हैं. इस तरह यह काम करता है
Kotlin फ़्लो की तरह
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
: कंपोज़ की स्थिति को फ़्लो में बदलें
snapshotFlow
का इस्तेमाल करें
State<T>
का फ़ॉर्मैट बदलने के लिए
चीज़ों को ठंडे प्रवाह में ले जाएं. इकट्ठा किए जाने और उत्सर्जन होने पर snapshotFlow
अपने ब्लॉक को ट्रिगर करता है
उसमें पढ़े गए State
ऑब्जेक्ट का नतीजा मिलेगा. जब State
ऑब्जेक्ट में से कोई एक
snapshotFlow
ब्लॉक म्यूटेट के अंदर पढ़ें, फ़्लो नई वैल्यू को छोड़ देगा
अपने कलेक्टर में तब जोड़ेगा, जब नई वैल्यू इसके बराबर न हो
पिछला उत्सर्जित मान (यह व्यवहार इसके समान है
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
को ऐसे फ़्लो में बदल दिया जाता है जो
को फ़्लो के ऑपरेटर की ताकत का फ़ायदा मिल सकता है.
इफ़ेक्ट रीस्टार्ट किए जा रहे हैं
कंपोज़ की सुविधा में मौजूद कुछ इफ़ेक्ट, जैसे कि 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)
}
}
}
DisposableEffect
के तौर पर currentOnStart
और currentOnStop
की ज़रूरत नहीं है
कुंजियों की वजह से, कंपोज़िशन में उनकी वैल्यू कभी नहीं बदलती है. ऐसा इसलिए, क्योंकि
rememberUpdatedState
. अगर आप lifecycleOwner
को पैरामीटर के रूप में पास नहीं करते हैं और
यह बदल जाता है, HomeScreen
फिर से हो जाता है, लेकिन DisposableEffect
को नष्ट नहीं किया जाता है
में से चुनें और रीस्टार्ट किया गया. इससे गड़बड़ी होती है, क्योंकि गलत lifecycleOwner
उसके बाद से इस्तेमाल किया जा रहा है.
कॉन्स्टेंट को कुंजियों के रूप में
true
जैसे कॉन्स्टेंट को इफ़ेक्ट बटन के तौर पर इस्तेमाल किया जा सकता है
उसे कॉल साइट की लाइफ़साइकल को फ़ॉलो करने के लिए सेट करना होगा. कुछ मामलों में,
, जैसा कि LaunchedEffect
उदाहरण ऊपर दिखाया गया है. हालांकि, ऐसा करने से पहले,
अच्छी तरह से सोचें और पक्का करें कि आपको यही टूल चाहिए.
आपके लिए सुझाव
- ध्यान दें: JavaScript बंद होने पर लिंक टेक्स्ट दिखता है
- स्टेट और Jetpack Compose
- Jetpack Compose के लिए Kotlin
- Compose में व्यू का इस्तेमाल करना