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

Support React v16 when editor is focused after removed from DOM #1409

Closed
wants to merge 4 commits into from

Conversation

mattkrick
Copy link
Contributor

Summary

  • calling Style.getScrollParent(editorNode) with null will result in an uncaught error
  • Ref#focus() is often called within a setTimeout (even in some example IIRC). Ref doesn't get GCd, but the DOM node it points to may no longer exist. Since React v16 is so blazing fast, it's possible that we're trying to focus something that no longer exists.
  • Without this bit of code, we'd have to call findDOMNode on the ref before calling focus. That's not great since putting findDOMNode is discouraged in application code.

@flarnie
Copy link
Contributor

flarnie commented Oct 3, 2017

Interesting - Seems like another option would be to release the timeout in componentWillUnmount, and that is generally what I would want to do.

That said, it looks like the main reason we added this invariant was to improve type strictness, and having an early return does the same thing effectively of validating the type before continuing execution.

I'm inclined to accept this, since I can't think of a big difference in effect between cleaning up the timeout on unmount and not throwing when it isn't cleaned up - but this way is more convenient for the engineer.

Adding this to my queue for merging - thanks @mattkrick !

Copy link

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@flarnie is landing this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@sophiebits
Copy link
Contributor

Maybe it would be cleaner to return if !editorNode then keep the invariant? Then we'll notice more explicitly if that's no longer true rather then it silently failing.

@flarnie
Copy link
Contributor

flarnie commented Oct 4, 2017

Oh - I like that! Will revise this and re-rebase/etc. tomorrow. :)

@mattkrick
Copy link
Contributor Author

i'm not sure i understand the change but as long as the function terminates without an error with the editorNode doesn't exist i'm happy!

flarnie and others added 2 commits October 8, 2017 19:05
**what is the change?:**
The problem - we currently throw if '_focus' receives an invalid type of
editorNode.

But in some cases the editorNode is null, and it's pretty
convenient/harmless to fail silently there.

So the proposed change was to fail silently if the editorNode was an
invalid type.

However, it's a bit stricter to fail only if the editorNode is undefined
or null, which is the case this is meant to address. If we get some
other type of thing as the editorNode somehow, then we still throw.

**why make this change?:**
To be slightly stricter and still solve the problem.

**test plan:**
Didn't really test it! :D

**issue:**
No issue open afaik
Copy link

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@flarnie is landing this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

if (!(editorNode instanceof HTMLElement)) {
if (!editorNode) {
// once in a while people call 'focus' in a setTimeout, and the node has
// been deleted, so it can be null in that case.
return;
}

const scrollParent = Style.getScrollParent(editorNode);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

correct me if I'm wrong, but Style.getScrollParent has 1 param & that is node, so we don't want to call it unless we have an HTMLElement, right? It doesn't matter either way (code below), but if we were writing a unit test for this, then it'd be REALLY hard to reach that invariant...

getScrollParent: function getScrollParent(node) {
	    if (!node) {
	      return null;
	    }
            ...

Copy link

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@flarnie has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

Copy link

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@flarnie has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@flarnie
Copy link
Contributor

flarnie commented Oct 10, 2017

radish_spirit_dance

@flarnie flarnie added this to the v0.10.4 milestone Oct 10, 2017
midas19910709 added a commit to midas19910709/draft-js that referenced this pull request Mar 30, 2022
Summary:
**Summary**
- calling `Style.getScrollParent(editorNode)` with `null` will result in an uncaught error
- `Ref#focus()` is often called within a `setTimeout` (even in some example IIRC). `Ref` doesn't get GCd, but the DOM node it points to may no longer exist. Since React v16 is so blazing fast, it's possible that we're trying to focus something that no longer exists.
- Without this bit of code, we'd have to call `findDOMNode` on the ref before calling `focus`. That's not great since putting `findDOMNode` is discouraged in application code.
Closes facebookarchive/draft-js#1409

Differential Revision: D5976879

fbshipit-source-id: f8f63525fdb6e76a111ea72edae1a620505f3e93
alicayan008 pushed a commit to alicayan008/draft-js that referenced this pull request Jul 4, 2023
Summary:
**Summary**
- calling `Style.getScrollParent(editorNode)` with `null` will result in an uncaught error
- `Ref#focus()` is often called within a `setTimeout` (even in some example IIRC). `Ref` doesn't get GCd, but the DOM node it points to may no longer exist. Since React v16 is so blazing fast, it's possible that we're trying to focus something that no longer exists.
- Without this bit of code, we'd have to call `findDOMNode` on the ref before calling `focus`. That's not great since putting `findDOMNode` is discouraged in application code.
Closes facebookarchive/draft-js#1409

Differential Revision: D5976879

fbshipit-source-id: f8f63525fdb6e76a111ea72edae1a620505f3e93
aforismesen added a commit to aforismesen/draft-js that referenced this pull request Jul 12, 2024
Summary:
**Summary**
- calling `Style.getScrollParent(editorNode)` with `null` will result in an uncaught error
- `Ref#focus()` is often called within a `setTimeout` (even in some example IIRC). `Ref` doesn't get GCd, but the DOM node it points to may no longer exist. Since React v16 is so blazing fast, it's possible that we're trying to focus something that no longer exists.
- Without this bit of code, we'd have to call `findDOMNode` on the ref before calling `focus`. That's not great since putting `findDOMNode` is discouraged in application code.
Closes facebookarchive/draft-js#1409

Differential Revision: D5976879

fbshipit-source-id: f8f63525fdb6e76a111ea72edae1a620505f3e93
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants