mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-15 03:33:59 +02:00
fix: text content not rendered on ssr (#4798)
This commit is contained in:
5
.changeset/rude-humans-marry.md
Normal file
5
.changeset/rude-humans-marry.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'slate-react': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Fix text not rendered on ssr
|
@@ -61,6 +61,10 @@ const TextString = (props: { text: string; isTrailing?: boolean }) => {
|
|||||||
|
|
||||||
const ref = useRef<HTMLSpanElement>(null)
|
const ref = useRef<HTMLSpanElement>(null)
|
||||||
|
|
||||||
|
const getTextContent = () => {
|
||||||
|
return `${text ?? ''}${isTrailing ? '\n' : ''}`
|
||||||
|
}
|
||||||
|
|
||||||
// This is the actual text rendering boundary where we interface with the DOM
|
// 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,
|
// 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
|
// 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
|
// useLayoutEffect: updating our span before browser paint
|
||||||
useIsomorphicLayoutEffect(() => {
|
useIsomorphicLayoutEffect(() => {
|
||||||
// null coalescing text to make sure we're not outputing "null" as a string in the extreme case it is nullish at runtime
|
// 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) {
|
if (ref.current && ref.current.textContent !== textWithTrailing) {
|
||||||
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 <span> below" on each render
|
// as this effectively replaces "specifying the text in the virtual DOM under the <span> 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 (
|
||||||
|
<span data-slate-string ref={ref}>
|
||||||
|
{getTextContent()}
|
||||||
|
</span>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// the span is intentionally same on every render in virtual DOM, actual rendering happens in the layout effect above
|
// the span is intentionally same on every render in virtual DOM, actual rendering happens in the layout effect above
|
||||||
return <span data-slate-string ref={ref} />
|
return <span data-slate-string ref={ref} />
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user