<@UHAJKUSTU> Hi, If I create a lifecycle via ```fu...
# decompose
e
@Arkadii Ivanov Hi, If I create a lifecycle via
Copy code
fun LifecycleRegistry(): LifecycleRegistry = LifecycleRegistry(initialState = Lifecycle.State.INITIALIZED)
and then pass it to the child component via
fun <Ctx : GenericComponentContext<Ctx>> Ctx.childContext(key: String, lifecycle: Lifecycle? = null): Ctx
I get this error when I try to destroy the component:
Copy code
"The lifecycle of a child ComponentContext must never be destroyed manually."
I am just calling
onDestroy
on the LifecycleRegistry. What is the correct way to create own lifecycle and put it into
DESTROYED
state? What I am trying to achieve is to get child component removed correctly from the
stateKeeper
when I actually have destroyed it.
a
You are using childContext incorrectly. Since it's an extension on ComponentContext, it's automatically lifecycle-aware. You only need to pass the lifecycle argument if you want to control the child lifecycle manually. See https://arkivanov.github.io/Decompose/component/child-components/#adding-a-child-component-manually
e
In my case I am using it the same way as in the example. But I don’t understand how to destroy the child component separately while the parent is still alive. Otherwise the stateKeeper doesn’t allow to recreate the child component and add it again with the same key.
a
So it will crash if you pass the same lifecycle to
childContext
. The passed lifecycle is expected to be never destroyed. Please see the docs: https://arkivanov.github.io/Decompose/component/child-components/#adding-a-child-component-manually
But permanent child components must never be destroyed manually.
If you need to dynamically create and destroy a child component, then you need navigation. You can try Child Slot.
e
Understood. My case is the following. I am already using a stack navigation. The only reason of creating child component manually is to get access to it directly from the parent component. As I understand the Child Slot will not help me with that and it would be in this aspect the same as with stack navigation. But because this child component can be added and removed from the stack it needs to be recreated like others in the stack.
So maybe my approach is not correct in general. Should I just use the componentContext from the childFactory and save the reference to the created component somewhere in a nullable var and clean it when it is removed from the stack?
It looks like a pretty common scenario, what is the best practice for getting such access to the child from the parent?
a
I think you just need to replace childContext with childSlot, and it should work as you expect. It would be nice to see some code otherwise.
e
I have ended with the following solution:
Copy code
private val selfieComponentDisposableDelegate = disposableManually<SelfieRootComponent>()

private var selfieTakerComponent by selfieComponentDisposableDelegate
and inside the childFactory:
Copy code
Configuration.ReplaceSelfie -> {
                createReplaceSelfieComponent(childComponentContext).also { createdComponent ->
                    selfieComponentDisposableDelegate.restore()
                    selfieTakerComponent = createdComponent
                    childComponentContext.lifecycle.doOnDestroy {
                        selfieComponentDisposableDelegate.dispose()
                    }
                }
                Child.ReplaceSelfie(selfieTakerComponent)
            }
In such way I have not nullable var which is easy to access and it is recreated along with navigation. (Accessing to it between disposal and recreation throws exception)
I don’t like this solution much, since it is too verbose and complicated. But it works.
a
This looks unnecessarily complicated. Maybe you could describe your use case in more detail? I believe there should be a better solution.
Is it correct that you need a non-nullable replaceable child?
e
There is a child flow which is absolutely normal and regular. It is added to a stack as others. But this flow contains a selfie taker which has an image as an output. And the parent component needs access to that image. The child could be nullable in theory, it will remove disposableDelegate and will allow to just set the nullable var. Maybe it is the way to go.
a
Sorry, it's still not clear why you need to manually destroy a child component. Your selfie taker could deliver the photo to the parent via a callback. I could help you if you describe your exact case in more detail. But you are ok with the solution you discovered, that's also fine.
e
I don’t need to manually destroy the component now. I only try to get a convenient way to access it, while it being managed by the stack navigation. I think you are right and the source of the problem is the direct access to the component. Initially when I just started with Decompose I understood that there are 2 possible ways to get data from the child: callbacks and such direct access. But it turns out that if the child could be recreated (as a part of a stack) the direct access creates more issues than profit. I will try to avoid this direct access and it should solve the issue. Thank you for help!
a
Thanks for the clarification! Just in case, you can directly access any child within the stack by just reading the ChildStack state.
💪 1
thank you color 1