facebook / facebook/lexical

Bug: async updates cause unwanted history

Open
#4,171 17 comments 8 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
23.9k
Forks
2.2k
Avg merge
1d 14h
Merged PRs (30d)
55

Description

There's a class of bugs involving async actions that leaves the history stack in an unwanted state. The problem occurs when a future update needs to replace a past update such as when uploading an image. Typically, an image node is inserted with a loading state because we don't know the `src` until it's uploaded. Eventually, we'll set the `src` as the result of an async action. If the async update is not merged then it's possible to "undo" back to the image's initial loading state which the user would never want.

Updates that use `discrete: true` and the `history-merge` tag will properly squash the update, but _only if there have been no other updates in between_. There's no way to merge a new update into a previous update of arbitrary position in the history stack.

The current way to solve this is to track data in a separate map keyed by node key. It's cumbersome and feels like something that the library should provide a built-in solution for.

Lexical version: 0.9.0 (and earlier)

## Steps To Reproduce

1. Insert an image node with a loading indicator. Asynchronously upload the desired image to your backend of choice.
2. Make random edits unrelated to the image
3. When the async upload finishes, update the placeholder image node with the new `src` attribute.
4. Trigger "undo" to reset the editor to state (2) where the image is still loading

Link to code example: https://codesandbox.io/s/lexical-plain-text-example-forked-usgq8e?file=/src/Editor.js

## The current behavior

The user can "undo" back to an unwanted loading state.

## The expected behavior

Previous history should be overwritten so that the user cannot return to unwanted loading states.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.