mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-18 13:11:17 +02:00
implement isomorphic layout effect (#3262)
supresses warning on SSR when using useLayoutEffect by falling back to useEffect when window is undefined neither useLayoutEffect nor useEffect is run on server
This commit is contained in:
committed by
Ian Storm Taylor
parent
1389093f06
commit
56d798a943
@@ -1,10 +1,4 @@
|
||||
import React, {
|
||||
useLayoutEffect,
|
||||
useEffect,
|
||||
useRef,
|
||||
useMemo,
|
||||
useCallback,
|
||||
} from 'react'
|
||||
import React, { useEffect, useRef, useMemo, useCallback } from 'react'
|
||||
import { Editor, Element, NodeEntry, Node, Range, Text } from 'slate'
|
||||
import debounce from 'debounce'
|
||||
import scrollIntoView from 'scroll-into-view-if-needed'
|
||||
@@ -15,6 +9,7 @@ import { IS_FIREFOX, IS_SAFARI } from '../utils/environment'
|
||||
import { ReactEditor } from '..'
|
||||
import { ReadOnlyContext } from '../hooks/use-read-only'
|
||||
import { useSlate } from '../hooks/use-slate'
|
||||
import { useIsomorphicLayoutEffect } from '../hooks/use-isomorphic-layout-effect'
|
||||
import {
|
||||
DOMElement,
|
||||
DOMNode,
|
||||
@@ -106,7 +101,7 @@ export const Editable = (
|
||||
)
|
||||
|
||||
// Update element-related weak maps with the DOM element ref.
|
||||
useLayoutEffect(() => {
|
||||
useIsomorphicLayoutEffect(() => {
|
||||
if (ref.current) {
|
||||
EDITOR_TO_ELEMENT.set(editor, ref.current)
|
||||
NODE_TO_ELEMENT.set(editor, ref.current)
|
||||
@@ -121,7 +116,7 @@ export const Editable = (
|
||||
// leaky polyfill that only fires on keypresses or clicks. Instead, we want to
|
||||
// fire for any change to the selection inside the editor. (2019/11/04)
|
||||
// https://github.com/facebook/react/issues/5785
|
||||
useLayoutEffect(() => {
|
||||
useIsomorphicLayoutEffect(() => {
|
||||
window.document.addEventListener('selectionchange', onDOMSelectionChange)
|
||||
|
||||
return () => {
|
||||
@@ -136,7 +131,7 @@ export const Editable = (
|
||||
// built-in `onBeforeInput` is actually a leaky polyfill that doesn't expose
|
||||
// real `beforeinput` events sadly... (2019/11/04)
|
||||
// https://github.com/facebook/react/issues/11211
|
||||
useLayoutEffect(() => {
|
||||
useIsomorphicLayoutEffect(() => {
|
||||
if (ref.current) {
|
||||
// @ts-ignore The `beforeinput` event isn't recognized.
|
||||
ref.current.addEventListener('beforeinput', onDOMBeforeInput)
|
||||
@@ -151,7 +146,7 @@ export const Editable = (
|
||||
}, [])
|
||||
|
||||
// Whenever the editor updates, make sure the DOM selection state is in sync.
|
||||
useLayoutEffect(() => {
|
||||
useIsomorphicLayoutEffect(() => {
|
||||
const { selection } = editor
|
||||
const domSelection = window.getSelection()
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import React, { useLayoutEffect, useRef } from 'react'
|
||||
import React, { useRef } from 'react'
|
||||
import getDirection from 'direction'
|
||||
import { Editor, Node, Range, NodeEntry, Element as SlateElement } from 'slate'
|
||||
|
||||
@@ -6,6 +6,7 @@ import Text from './text'
|
||||
import Children from './children'
|
||||
import { ReactEditor, useEditor, useReadOnly } from '..'
|
||||
import { SelectedContext } from '../hooks/use-selected'
|
||||
import { useIsomorphicLayoutEffect } from '../hooks/use-isomorphic-layout-effect'
|
||||
import {
|
||||
NODE_TO_ELEMENT,
|
||||
ELEMENT_TO_NODE,
|
||||
@@ -111,7 +112,7 @@ const Element = (props: {
|
||||
}
|
||||
|
||||
// Update element-related weak maps with the DOM element ref.
|
||||
useLayoutEffect(() => {
|
||||
useIsomorphicLayoutEffect(() => {
|
||||
if (ref.current) {
|
||||
KEY_TO_ELEMENT.set(key, ref.current)
|
||||
NODE_TO_ELEMENT.set(element, ref.current)
|
||||
|
@@ -1,9 +1,10 @@
|
||||
import React, { useLayoutEffect, useRef } from 'react'
|
||||
import React, { useRef } from 'react'
|
||||
import { Range, Element, Text as SlateText } from 'slate'
|
||||
|
||||
import Leaf from './leaf'
|
||||
import { ReactEditor, useEditor } from '..'
|
||||
import { RenderLeafProps } from './editable'
|
||||
import { useIsomorphicLayoutEffect } from '../hooks/use-isomorphic-layout-effect'
|
||||
import {
|
||||
KEY_TO_ELEMENT,
|
||||
NODE_TO_ELEMENT,
|
||||
@@ -44,7 +45,7 @@ const Text = (props: {
|
||||
}
|
||||
|
||||
// Update element-related weak maps with the DOM element ref.
|
||||
useLayoutEffect(() => {
|
||||
useIsomorphicLayoutEffect(() => {
|
||||
if (ref.current) {
|
||||
KEY_TO_ELEMENT.set(key, ref.current)
|
||||
NODE_TO_ELEMENT.set(text, ref.current)
|
||||
|
@@ -0,0 +1,7 @@
|
||||
import { useLayoutEffect, useEffect } from 'react'
|
||||
|
||||
/**
|
||||
* Prevent warning on SSR by falling back to useEffect when window is not defined
|
||||
*/
|
||||
export const useIsomorphicLayoutEffect =
|
||||
typeof window !== 'undefined' ? useLayoutEffect : useEffect
|
Reference in New Issue
Block a user