From 0e7515a3d85a7ad4313df558c8f5e3caca940a09 Mon Sep 17 00:00:00 2001 From: hueyhe Date: Fri, 21 Jan 2022 11:01:00 +0800 Subject: [PATCH] fix: text content not rendered on ssr --- .changeset/rude-humans-marry.md | 5 +++++ packages/slate-react/src/components/string.tsx | 16 +++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 .changeset/rude-humans-marry.md diff --git a/.changeset/rude-humans-marry.md b/.changeset/rude-humans-marry.md new file mode 100644 index 0000000000..f36db03bf0 --- /dev/null +++ b/.changeset/rude-humans-marry.md @@ -0,0 +1,5 @@ +--- +'slate-react': patch +--- + +Fix text not rendered on ssr diff --git a/packages/slate-react/src/components/string.tsx b/packages/slate-react/src/components/string.tsx index b77b14672b..7bd09c9888 100644 --- a/packages/slate-react/src/components/string.tsx +++ b/packages/slate-react/src/components/string.tsx @@ -61,6 +61,10 @@ const TextString = (props: { text: string; isTrailing?: boolean }) => { const ref = useRef(null) + const getTextContent = () => { + return `${text ?? ''}${isTrailing ? '\n' : ''}` + } + // This is the actual text rendering boundary where we interface with the DOM // The text is not rendered as part of the virtual DOM, as since we handle basic character insertions natively, // updating the DOM is not a one way dataflow anymore. What we need here is not reconciliation and diffing @@ -72,7 +76,7 @@ const TextString = (props: { text: string; isTrailing?: boolean }) => { // useLayoutEffect: updating our span before browser paint useIsomorphicLayoutEffect(() => { // null coalescing text to make sure we're not outputing "null" as a string in the extreme case it is nullish at runtime - const textWithTrailing = `${text ?? ''}${isTrailing ? '\n' : ''}` + const textWithTrailing = getTextContent() if (ref.current && ref.current.textContent !== textWithTrailing) { ref.current.textContent = textWithTrailing @@ -82,6 +86,16 @@ const TextString = (props: { text: string; isTrailing?: boolean }) => { // as this effectively replaces "specifying the text in the virtual DOM under the below" on each render }) + // Render text content immediately if it's the first-time render + // Ensure that text content is rendered on server-side rendering + if (!ref.current) { + return ( + + {getTextContent()} + + ) + } + // the span is intentionally same on every render in virtual DOM, actual rendering happens in the layout effect above return }