Screen Flows, part of Salesforce Flow, lets developers and administrators create user interfaces and tie them to Salesforce data using code or no-code tools. Screen flows allow developers to use Lightning Web Components (LWC) as flow elements. However, building LWCs for a flow requires that you follow some best practices. Doing so increases the performance of your LWCs, and your component works better within the Flow runtime engine.
In this blog, we first dive into how state management works in the Flow runtime, and then share some state management and event best practices that you should follow when building LWCs for your screen flows.
Best practices for LWC state management in screen flows
The Flow runtime adheres to LWC state management design principles. It works best when the LWC components that it renders do not modify their own
@api attributes and instead request that a change be made by firing
This pattern is essential for two reasons.
- Components that allow their parents to control their
@apiparameters are more easily reused because they allow the application to control the state rather than the component’s own internal business logic.
- By firing attribute change events, the Flow runtime can maintain an accurate picture of the component state, which allows it to control inter-component interactions, such as conditional field visibility.
Using Salesforce LWC’s linter rules is an excellent way to ensure that your component does not modify
@api parameters. Set up a linter that uses LWC’s linter rules in your development environment, specifically ensuring that the lwc/no-api-reassignments setting is enforced.
Below is an example of a simple text input component. It demonstrates how a
FlowAttributeChangeEvent should be fired in lieu of updating the LWC’s
Best practices for LWC events in screen flows
In the upcoming sections, we deep dive into best practices for flow events like
Attribute change event best practices
This section presents a list of
FlowAttributeChangeEvent (see docs) Dos and Don’ts.
- Do not modify
@apiattributes in the component. Instead, fire the
- Do fire the event in event handlers or in methods invoked within event handlers.
- Do limit the event’s value parameter to the following data types:
- JSON (for record types)
- Do ensure that the data type of the
FlowAttributeChangeEventvalue parameter matches the data type of the LWC’s
- Do react to changes to
@apiparameters by using a
get/setpattern where appropriate. This is also needed to cross-communicate between components when you are using reactive screen components (Beta).
The example below demonstrates using
get/set to count the updates to an
@api parameter vs. simply incrementing a counter before firing an attribute change event. It is worth noting that both the below patterns are valid but achieve slightly different results.
In the above scenario,
this.changeCounter will be incremented whenever the user inputs a change in the text input and whenever the Flow runtime determines that the
textValue property has changed. This will consider component initialization and cross-component interactions when using reactive screen components.
Note: an intermediate variable will need to be used to render updates from the set method. In this example, we introduce the
textValueToRenderfor this purpose.
Let’s look at a code example where we increment a counter before firing an attribute change event. In this scenario, we do not use the
In this case,
this.changeCounter will be incremented whenever the user inputs a change in the text input.
6. Do use anotationless or
@track parameters to maintain a modifiable local component state.
The example below shows a color picker that presents the user with an input text box and some swatches. Note that the color picker component returns color to the flow, so only
color needs to be an
@api parameter, the
inputValue members are internal only and hence do not need any decorator.
7. Do use a
get method to combine multiple
@api parameters together to construct a derived variable for the view.
8. Do apply the same logic in the
set method of every
@api parameter that contributes to a derived member variable. This is needed for internal component state management for complex scenarios. This will ensure that a change made to any contributing attribute will cause the value to render correctly, regardless of the order in which attributes are set.
9. Do not modify
FlowAttributeChangeEvent parameters after construction. By default,
FlowAttributeChangeEvent instances are composed and bubble.
10. Avoid firing
FlowNavigationXxx events at the same time. The rationale for this is it can lead to race conditions. There’s never a guarantee that the LWC component has had time to render the updated values by the time we start the navigation process.
Navigation change event best practices
In addition to the
FlowAttributeChangeEvent, custom LWCs can fire navigation events to move between screens and pause or finish flows.
The intent of navigation events is to allow for custom LWC authors to include additional control mechanisms within their components. To that end, navigation events should be fired when reacting to end-user interaction.
Consult the list of Dos and Don’ts below when planning on using navigation events.
- Do fire navigation events in event handlers (or in the method they invoke).
- Do not fire navigation events outside of event handlers as it leads to a poor experience for the end user.
- Do not fire navigation events in lifecycle handlers like
The logic for skipping screens should rest in Flow Decision Nodes and should not be determined during the lifecycle of a screen. Additionally, navigation in a dummy screen can lead to poor flow performance.
We love it when developers create innovative solutions with Lightning Web Components combined with Flows. Following the best practices outlined in this blog ensures that your components integrate well within the Flow runtime engine and work as expected.
About the authors
Josh Goodman is a Principal Member of the Technical Staff with over 7 years of experience as a developer at Salesforce. Through his tenure, Josh has worked on many exciting features such as adding Reports and Dashboards to Salesforce One mobile, bringing Wave Charting to Lightning, adding nested folder support to the Reports and Dashboard home pages, and converting the Flow UI to from Aura to LWC. He is currently working on exciting new UI runtime features for Flows.
Mohith Shrivastava is a Developer Advocate at Salesforce with a decade of experience building enterprise-scale products on the Salesforce Platform. He is presently focusing on the Salesforce Developer Tools, Flow, Apex, and Lightning Web Components at Salesforce. Mohith is currently among the lead contributors on Salesforce Stack Exchange, a developer forum where Salesforce Developers can ask questions and share knowledge. You can follow him via his Twitter @msrivastav13.