Skip to content
This repository was archived by the owner on Feb 6, 2023. It is now read-only.

Conversation

@conorhastings
Copy link

closes #1

@conorhastings conorhastings deleted the patch-1 branch February 23, 2016 02:53
facebook-github-bot pushed a commit that referenced this pull request Aug 17, 2017
Summary:
bypass-lint
ignore-conflict-markers
ignore-signed-source
ignore-nocommit

Reviewed By: avikchaudhuri

fbshipit-source-id: a37b2d6dbd09b90a1407f732001abb7aef21de79
facebook-github-bot pushed a commit that referenced this pull request Feb 16, 2018
Summary:
**tldr;** Handlers can get called after cWU and before cDU, and they use the
cached 'latestEditorState'. For them to get the fresh version of the state,
we need to update 'latestEditorState' in 'render' because that happens before
the handlers get called.

**The whole story;**
We are trying to remove cWU from `DraftEditor.react.js`. One thing which
currently happens there is that `latestEditorState` gets set to the
nextProps.editorState, so whatever is passed in by the parent. For more context
on the initial attempt at changing this, see
https://our.intern.facebook.com/intern/diff/D6873303/

This change introduced one bug that manifested in various ways - see T26034821
and T26020049. I'll focus on T26020049, which broke
`<AdsBulkTokenizedTextInputWithFieldsSelector>`.

`<AdsBulkTok...FieldsSelection>` has a button for adding a new token, and when
you hit that button it passes `<DraftEditor>` an updated editorState as a prop.
This triggers render #1, and during that render we update the browser
selection, which triggers `focus` and `blur` events. These each trigger another
render of `<DraftEditor>`; renders #2 and #3. Here is how it looks on a
timeline:
```
render #1
+
|
| cWU -> latestEditorState = FRESH_STATE
|
| render -> this.props.editorState = FRESH_STATE
| +
| |
| +--> triggers 'focus' event, calling 'handleFocus' with latestEditorState
|                   +
|                   |
+>cDU fires         | the 'handleFocus' call schedules render #2
                    | with latestEditorState, which is FRESH_STATE
                    |
render #2  <--------+
+
|
| cWU -> latestEditorState = FRESH_STATE
|
| render -> this.props.editorState = FRESH_STATE
|
+>cDU fires
```
When we move the update of latestEditorState to cDM, things go awry like this;
```
render #1
+
|
| cWU -> Nothing ... latestEditorState = STALE_STATE :(
|
| render -> this.props.editorState = FRESH_STATE
| +
| |
| +--> triggers 'focus' event, calling 'handleFocus' with latestEditorState
|                                                +
|                                                |
+>cDU -> latestEditorState = FRESH_STATE         | the 'handleFocus' call schedules render #2
                                                 | with latestEditorState, which is STALE_STATE :(
                                                 |
render #2 <--------------------------------------+
+
|
| cWU -> nothing updates
|
| render -> this.props.editorState = STALE_STATE :(  because this was passed in above
|
+>cDU fires and resets latestEditorState = STALE_STATE :(
```

So we can fix things by updating latestEditorState inside the `render` method,
like so;
```
render #1
+
|
| cWU -> Nothing ... latestEditorState = STALE_STATE :(
|
| render -> this.props.editorState = FRESH_STATE
| +         *and* set latestEditorState = FRESH_STATE
  |
| |
| +--> triggers 'focus' event, calling 'handleFocus' with latestEditorState
|                                                +
|                                                |
+>cDU -> latestEditorState = FRESH_STATE         | the 'handleFocus' call schedules render #2
                                                 | with latestEditorState, which is FRESH_STATE
                                                 |
render #2 <--------------------------------------+
+
|
| cWU -> nothing updates
|
| render -> this.props.editorState = FRESH_STATE which was passed in above
|
+>cDU fires and resets latestEditorState = FRESH_STATE
```

One possible issue would be if `render` fired and then was never completed, in
async. mode, but since Draft is intended to always be run in sync. mode I'm not
worried about that.

Reviewed By: mitermayer

Differential Revision: D6994261

fbshipit-source-id: 80986b853a57f64aa5aafbe667b4d94171d5271c
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fix getting started link

1 participant