@Retention(value=RUNTIME)
public @interface State
State
in the
spec. While both Prop
and State
hold information that influences the output of
the component, they are different in one important way: props get passed to the component from
its parent whereas states are managed within the component.
The initial values of states can be set using the OnCreateInitialState
method and
states can be updated in OnUpdateState
methods. Updating states in the OnUpdateState
methods will cause the component to invoke its OnCreateLayout
method.
States should be immutable since the layout can be calculated on multiple threads.
Immutability of the states ensures that no thread safety issues can occur in the component
hierarchy.
Using State:
@LayoutSpec
public class CounterSpec {
@OnCreateLayout
static Component onCreateLayout(
ComponentContext c,
@State int count) {
return Row.create(c)
.backgroundColor(Color.WHITE)
.heightDip(64)
.paddingDip(YogaEdge.ALL, 8)
.child(
Text.create(c)
.text(" + ")
.clickHandler(Counter.onClick(c))
)
.child(
Text.create(c)
.text(String.valueOf(count))
)
.build();
}
@OnCreateInitialState
static void onCreateInitialState(
ComponentContext c,
StateValue<Integer> count) {
count.set(0);
}
@OnEvent(ClickEvent.class)
static void onClick(ComponentContext c) {
Counter.increment(c);
}
@OnUpdateState
static void increment(StateValue<Integer> count) {
count.set(count.get() + 1);
}
}
Param
Modifier and Type | Optional Element and Description |
---|---|
boolean |
canUpdateLazily
Declares that this state can be updated lazily and that will not trigger a new layout
calculations.
|
public abstract boolean canUpdateLazily
Note: Such state can still participate in normal state update via OnUpdateState
methods, but for lazy state updates an additional lazyUpdate*StateName*
method will be generated.
Warning: For now, lazily updated values will be available only in OnEvent
methods (or after a normal state update). If you need support of other lifecycle methods, feel
free to file an issue.
Using State:
@LayoutSpec
public class MyComponentSpec {
@OnCreateLayout
static Component onCreateLayout(ComponentContext c) {
return Column.create(c)
.child(
Text.create(c)
.backgroundRes(R.drawable.button_background)
.textSizeSp(20)
.text("Submit")
.clickHandler(MyComponent.onClick(c)))
.build();
}
@OnEvent(ClickEvent.class)
static void onClick(ComponentContext c, @State(canUpdateLazily = true) boolean wasAlreadyClicked) {
if (!wasAlreadyClicked) {
logFirstButtonClick();
}
MyComponent.lazyUpdateWasAlreadyClicked(c, true);
}
}
true
if this state can be updated lazily.