Skip to content

//workflow/com.squareup.workflow1/StatefulWorkflow

StatefulWorkflow

[jvm] abstract class StatefulWorkflowPropsT, StateT, out OutputT, out RenderingT> : Workflow<PropsT, OutputT, RenderingT>

A composable, stateful object that can handle events, delegate to children, subscribe to arbitrary asynchronous events from the outside world, and be saved to a serialized form to be restored later.

The basic purpose of a Workflow is to take some props and return a rendering that serves as a public representation of its current state, and which can be used to update that state. A rendering typically serves as a view model, though this is not assumed, and is not the only use case.

To that end, a workflow may keep track of internal state, recursively ask other workflows to render themselves, subscribe to data streams from the outside world, and handle events both from its renderings and from workflows it’s delegated to (its “children”). A Workflow may also emit output events up to its parent Workflow.

Workflows form a tree, where each workflow can have zero or more child workflows. Child workflows are started as necessary whenever another workflow asks for them, and are cleaned up automatically when they’re no longer needed. Props propagate down the tree, outputs and renderings propagate up the tree.

Avoid capturing stale state

Workflows may not perform side effects in their render methods, but may perform side effects by running Workers and getting events from RenderingTs via WorkflowActions. A WorkflowAction defines how to update the StateT and what OutputTs to emit. Actions get access to the current workflow’s state, and they must use that view of the state. If an action is defined inline, it is incorrect to capture, or close over, the StateT passed to render in the action. Workflows are executed synchronously, but external events may not be, so captured state may be stale when the action is invoked.

See also

jvm

com.squareup.workflow1.StatelessWorkflow

Parameters

jvm

PropsT

Typically a data class that is used to pass configuration information or bits of state that the workflow can always get from its parent and needn’t duplicate in its own state. May be Unit if the workflow does not need any props data.

StateT

Typically a data class that contains all of the internal state for this workflow. The state is seeded via props in initialState. It can be serialized and later used to restore the workflow. Implementations of the Workflow interface should not generally contain their own state directly. They may inject objects like instances of their child workflows, or network clients, but should not contain directly mutable state. This is the only type parameter that a parent workflow needn’t care about for its children, and may just use star (*) instead of specifying it. May be Unit if the workflow does not have any internal state (see StatelessWorkflow).

OutputT

Typically a sealed class that represents “events” that this workflow can send to its parent. May be Nothing if the workflow doesn’t need to emit anything.

RenderingT

The value returned to this workflow’s parent during composition. Typically represents a “view” of this workflow’s props, current state, and children’s renderings. A workflow that represents a UI component may use a view model as its rendering type.

Constructors

StatefulWorkflow [jvm] fun StatefulWorkflow()Typically a data class that is used to pass configuration information or bits of state that the workflow can always get from its parent and needn’t duplicate in its own state.

Types

Name Summary
RenderContext [jvm]
Content
inner class RenderContext : BaseRenderContext<@UnsafeVariance()PropsT, StateT, @UnsafeVariance()OutputT>


Functions

Name Summary
asStatefulWorkflow [jvm]
Content
override fun asStatefulWorkflow(): StatefulWorkflow<PropsT, StateT, OutputT, RenderingT>
More info
Satisfies the Workflow interface by returning this.


initialState [jvm]
Content
abstract fun initialState(props: PropsT, snapshot: Snapshot?): StateT
More info
Called from RenderContext.renderChild when the state machine is first started, to get the initial state.


onPropsChanged [jvm]
Content
open fun onPropsChanged(old: PropsT, new: PropsT, state: StateT): StateT
More info
Called from RenderContext.renderChild instead of initialState when the workflow is already running.


render [jvm]
Content
abstract fun render(renderProps: PropsT, renderState: StateT, context: StatefulWorkflow.RenderContext<PropsT, StateT, OutputT, RenderingT>): RenderingT
More info
Called at least once† any time one of the following things happens:
  • This workflow’s renderProps changes (via the parent passing a different one in).
  • This workflow’s renderState changes.
  • A descendant (immediate or transitive child) workflow:
    • Changes its internal state.
    • Emits an output.
Never call this method directly.


snapshotState [jvm]
Content
abstract fun snapshotState(state: StateT): Snapshot?
More info
Called whenever the state changes to generate a new Snapshot of the state.


Extensions

Name Summary
action [jvm]
Content
fun <PropsT, StateT, OutputT, RenderingT> StatefulWorkflow<PropsT, StateT, OutputT, RenderingT>.action(name: String = “”, update: WorkflowAction.Updater<PropsT, StateT, OutputT>.() -> Unit): WorkflowAction<PropsT, StateT, OutputT>
fun <PropsT, StateT, OutputT, RenderingT> StatefulWorkflow<PropsT, StateT, OutputT, RenderingT>.action(name: () -> String, update: WorkflowAction.Updater<PropsT, StateT, OutputT>.() -> Unit): WorkflowAction<PropsT, StateT, OutputT>
More info
Convenience to create a WorkflowAction with parameter types matching those of the receiving StatefulWorkflow.


launchForTestingFromStateWith [jvm]
Content
@TestOnly()

fun <T, PropsT, StateT, OutputT, RenderingT> StatefulWorkflow<PropsT, StateT, OutputT, RenderingT>.launchForTestingFromStateWith(props: PropsT, initialState: StateT, context: CoroutineContext = EmptyCoroutineContext, block: WorkflowTestRuntime<PropsT, OutputT, RenderingT>.() -> T): T
@TestOnly()

fun <StateT, OutputT, RenderingT> StatefulWorkflow<Unit, StateT, OutputT, RenderingT>.launchForTestingFromStateWith(initialState: StateT, context: CoroutineContext = EmptyCoroutineContext, block: WorkflowTestRuntime<Unit, OutputT, RenderingT>.() -> Unit)
More info
Creates a WorkflowTestRuntime to run this workflow for unit testing.


launchForTestingWith [jvm]
Content
@TestOnly()

fun <T, PropsT, StateT, OutputT, RenderingT> StatefulWorkflow<PropsT, StateT, OutputT, RenderingT>.launchForTestingWith(props: PropsT, testParams: WorkflowTestParams<StateT> = WorkflowTestParams(), context: CoroutineContext = EmptyCoroutineContext, block: WorkflowTestRuntime<PropsT, OutputT, RenderingT>.() -> T): T
More info
Creates a WorkflowTestRuntime to run this workflow for unit testing.


testRender [jvm]
Content
fun <PropsT, StateT, OutputT, RenderingT> StatefulWorkflow<PropsT, StateT, OutputT, RenderingT>.testRender(props: PropsT, initialState: StateT): RenderTester<PropsT, StateT, OutputT, RenderingT>
More info
Create a RenderTester to unit test an individual render pass of this workflow.