also, should we use @Model or +state?
# compose
t
also, should we use @Model or +state?
m
don't we need to use state when we use @Model?
z
But drop the
+
in front of
state
I think if you’re using
@Model
you’ll want to use
remember
👍 1
j
@Matthewdhowell No, not if you hoist your state/data up, such that your application is holding the data model (ie. above Compose) and just pass it down. @Zach Klippenstein (he/him) [MOD] Yes, if you're using dev04+, you can drop the
+
.
👍 1
t
so no + in front of the state?
👍 1
so for more complex objects like a chat message with multiple fields
how would i express that?
z
Copy code
val myModel = remember { MyModel() }
Although ideally pulling your state up is better like @jim is suggesting.
c
state
returns an
@Model
object which contains one field so it is not either one or the other but just different shades of
@Model
.
m
in the hoisting situation, we create an ambient and give it an AmbientProvider then we can pull our model out of ambient() ?
🤦‍♂️ 1
does the ambient in that case need to be globally available?
z
Don’t use ambients for this, the Google team has strongly discouraged their use for anything other than extremely generic configuration-type data.
😍 2
👆 2
Just pass data down through regular parameters
😍 1
👆 1
so for more complex objects like a chat message with multiple fields
Ideally make it a data class (and I think annotate with
@Immutable
?), and pass instances of the data class around.
m
interesting
so all my composables need to pass their params on?
I thought that was what ambient worked against
z
so all my composables need to pass their params on?
Not necessarily. Another technique is to make generic composables that take composable functions as parameters, effectively acting as a “black box” to pass data down.
True, ambients allow you to magically pass values around the tree. But relying on them a lot will make your code an unmaintainable mess (talk to any React developer about Contexts).
c
One of problems with ambients is that they introduce a hidden dependency between the provider the consumer that the compiler doesn't validate. For model objects, this is particularly bad as the model is particularly important to understanding the coupling in an application.
t
I like react context 🙂
m
right I see, so I can pass some data dictionary of @models thru the @composables and they will be observed when I read/use them just because they are a @Model
c
That would work. That, at least, make the contract more explicit. However, the dictionary key is might hide the dependency. It might make sense to just have a
@Model
container object of the models and use the fields to access them. This way the type checker can validate that dependency is supplied. You can then use interfaces to abstract the dependencies between modules where the root model implements the model interfaces for the dependent modules/components.
👍 1
This way you can have unit tests that just implement the module model interfaces for the module.
t
so would something like this be the right approach?
in react the best practice is to use immutable objects
m
yeah, okay that makes sense, close to where I was going, thanks! @Thierry similarly, I think you may be looking to create a @Model that holds your message instances and the message class would be a @model , so when the message list changes or any message's properties change, your composition recomposes ..
t
two things that weren't clear from the docs: • when does something rerender in jetpack compose • what's the point of @model?
the jetnews sample app only seems to use dataclasses and no @model syntax
m
I thought that example uses @model for the state of whatscreen the user has navigated to
it uses remember with the model and the model is an object
t
you are right
m
it wasnt super clear to me what the relationship of remember is to the @Model
t
all the other state is data classes
and then you have this 1 model, react doesn't have the model concept so im not sure what it does
m
it basically wraps the object/class so that when it's properties are mutated, the composition recomposes
t
ok so if i use immutable data classes i have no need for model right? it looks like you only need model if you dont want immutability
m
is that right?
t
this example for instance looks like it could just be done using the state syntax
m
i am creating an ArrayList from my mutable list and swapping it into my @Model prop
in that screencap code @Model looks like it is being observed because it is used in the @Composable
it was stated above that state returns a @Model wrapped version of whatever you pass it
so, I am guessing it is the same mechanism
give or take
maybe different in different contexts, but I think a better way to go is to keep your immutable data private to whatever is managing that state, and creating some kind of @Model class that holds your immutable versions of that same data. is that crazy? what am I missing there? is @Composable supposed to be fine with direct mutation of data? I don't know the big concerns, just been trying to ~ make app happen ~
I like the idea of using ambient for just my root model and making that root model implement the interfaces of any sub models needed in my @composable's. generally just thinking about not adding actual params to my functions. I suppose I just need to safely cast the model as needed in my @composables @Chuck Jazdzewski [G] is that reasonable? or is it still sketchy?
c
I believe any use of an ambient for model is a bit sketchy so this would qualify. It is really a matter of taste however and you know your requirements better than me.
👍🏻 1
m
thanks for your thoughts, super appreciated!
t
ok think i got the state part figure out now, thanks
👍 1