Skip to content

#3548320 Flicker free prop linking

Closes #3548320

There are two significant aspects to making this work:

Refactor the props form's formStateToStore to not use stale data

When a value changes in the props form, it (after the debounce delay) reaches formStateToStore, where we update our stores and make the necessary API requests.

In order to debounce a function defined in a React component, it needs to be made persistent - usually with useCallback or useRef.

In HEAD, formStateToStore took one argument: newFormState. The logic in formStateToStore also depends greatly on the inputAndUiData variable, which is defined one scope level up.

After an input is linked, the other inputs still had the useCallback-wrapped formStateToStore they were initially sent, which includes stale inputAndUiData. We address the stale inputAndUiData problem by simply making that an argument passed into the function, so it's always working with the current data. This made the formStateToStore implementations for Component & Page data different enough that I moved the debounce implmentation out of the shared inputBehaviors and into the form specific InputBehaviorsComponentPropsForm and InputBehaviorsEntityForm

Create an action specific to prop linking

Prop linking is technically a programmatic update - we are changing the value of a prop but it's not by interacting with it's corresponding form input (i.e. the linking of a text field is not done by interacting with that text input)

There is an updateExistingComponentValues action that deselects a component before updating the values, then reselects it after the update. This is what causes the flicker. This was not as big a problem for other uses because it's typically invoked from elsewhere in the UI.

I created a dedicated updateExistingComponentValuesForLinking that is very similar, but does not deselect/reselect and instead invokes additional actions to match the sequence of events that would occur during a form interaction. I tested to see if this could work with non-prop-linking scenarios and that was less successful - hence the separate updateExistingComponentValues and updateExistingComponentValuesForLinking. See the @todo in the code for more info

Edited by Ben Mullins

Merge request reports

Loading