Please help - how can I make "local state" of widg...
# compose
m
Please help - how can I make "local state" of widget that reflects to change and rebuilds the widget when changed? Here I want to change color of rectangle after click on it. But it's not rebuilt. I suppose I don't need global
@Model
class for this scenario.
Copy code
@Composable
fun MyRect(){
    var color = +memo{ Color.Green }
    Clickable(onClick = {
        color = Color.Red
    }) {
        ColoredRect(brush = SolidColor(color), height = 100.dp)
    }
}
l
val color = +state{ Color.Green }
works
you then need to unwrap the state with
color.value
when needed
g
var color by +state { Color.Green }
l
val*
m
Perfect, works. Thanks! I've seen
memo
somewhere, but that's probably for different thing.
g
if it will be val, how can you change it
l
You change
color.value
m
it's
val
actually. you change its
value
.
l
not
color
itself
g
i wrote
by
, not
=
m
Hmm. There are two variants.
var color by +state{ Color.Green }
looks nicer, it doesn't require the
.value
thing.
g
yeah, i've seen it in sources
l
Yeah, looks better, as they;re also planning to get rid of
+
m
And who knows for what is
memo
? 🤔
l
It’s an
Effect
l
both
val color = +state { ... }
and
var color by +state { ... }
will work.
we may at some point lint against
var
in a composable function that is not introduced by a property delegate. not sure yet though
i prefer the
var color by ...
version for a couple of reasons, but some people might consider that more magic, so up to you
👌 1
l
It looks nicer indeed
f
I say to get rid of the other way
Having multiple ways of doing the same thing is just confusing
m
Proper way is
var ... by
. You're interested in your variable, not the delegate that is behind providing its value.
👆 1
f
and also wars about the right way of doing it are not nice
l
it’s definitely something worth considering
in general i agree with “multiple ways of doing the same thing is bad”
but it’s hard to know where you draw the line here….
Copy code
val x = a
val y = x.first
val z = x.second
vs
Copy code
val (y, z) = a
should kotlin make the 1st way impossible?
l
YES
🧌 3
f
Hmm, I wrote a long message about why that's not the same thing, but that got deleted because of internet connectivity. Anyway, the conclusion is that at the very least there should be an inspection to use the
by
syntax and to only use the
by
syntax in official examples.
l
Why? What if I need a
State
object?
f
Why would you need a
State
object?
l
Maybe I want
component1
and
component2
f
Maybe
But why would you need a State object?
l
If you don’t have the state object you can’t get
compoent1
and
component2
of
State
Btw, I already said the
by
solution looks cleaner and I’d use that, but as @Leland Richardson [G] said it’s hard to know where to force something
f
oh, you mean
(someState,setSomeState)
l
yes
f
Why would you use this syntax over using
by
?
Right now it seems to me like that should begone too
g
Copy code
val state = +state { false }
Checkbox(checked = state.value, onCheckedChange =    state.component2())
var checked by state
f
```
That's... unreadable
I don't think that's desired
I would rather read
Copy code
var state by state { false }
Checkbox(checked = state.value, onCheckedChange  = {state = it})
But I could see
Copy code
val (state,setState) = state { false }
Checkbox(checked = state.value, onCheckedChange =    setState)
But is this tiny synctactic sugar really worth having 3 ways of doing the same thing?
l
Well that’s 2 ways of doing the same 😛
f
What do you mean? You can 1) do
Copy code
val (value,setValue)  = state { false }
2)
Copy code
val value = state {false}
3)
Copy code
var value by state { false }
l
Yeah, the second one is bundle into the first
What I meant was:
= +state{}
could be used for
1.
,
by
could not. Maybe that’s the reason for having both of them 🙂
a
the first one is a lot like react hooks
l
Well that’s because Compose is influenced by React as well, alongside by Flutter, Vue.js, Litho