Skip to content

Commit f0b28dc

Browse files
committed
refactor to fix perf warns
1 parent 22e9ccf commit f0b28dc

File tree

1 file changed

+83
-25
lines changed

1 file changed

+83
-25
lines changed

src/react-portable-text.tsx

Lines changed: 83 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ export function PortableText<B extends TypedObject = PortableTextBlock>({
6262
return <>{rendered}</>
6363
}
6464

65-
function getNodeRenderer (
65+
function getNodeRenderer(
6666
components: PortableTextReactComponents,
6767
handleMissingComponent: MissingComponentHandler,
6868
): NodeRenderer {
@@ -79,15 +79,15 @@ function getNodeRenderer (
7979
}
8080

8181
if (isPortableTextToolkitSpan(node)) {
82-
return renderSpan(node, index, key)
82+
return <RenderSpan key={key} renderNode={renderNode} components={components} handleMissingComponent={handleMissingComponent} node={node} />
8383
}
8484

8585
if (hasCustomComponentForNode(node)) {
8686
return renderCustomBlock(node, index, key, isInline)
8787
}
8888

8989
if (isPortableTextBlock(node)) {
90-
return renderBlock(node, index, key, isInline)
90+
return <RenderBlock key={key} renderNode={renderNode} components={components} handleMissingComponent={handleMissingComponent} node={node} index={index} isInline={isInline} />
9191
}
9292

9393
if (isPortableTextToolkitTextNode(node)) {
@@ -196,28 +196,6 @@ function getNodeRenderer (
196196
)
197197
}
198198

199-
function renderBlock(node: PortableTextBlock, index: number, key: string, isInline: boolean) {
200-
const {_key, ...props} = serializeBlock({
201-
node,
202-
index,
203-
isInline,
204-
renderNode,
205-
})
206-
const style = props.node.style || 'normal'
207-
const handler =
208-
typeof components.block === 'function' ? components.block : components.block[style]
209-
const Block = handler || components.unknownBlockStyle
210-
211-
if (Block === components.unknownBlockStyle) {
212-
handleMissingComponent(unknownBlockStyleWarning(style), {
213-
nodeType: 'blockStyle',
214-
type: style,
215-
})
216-
}
217-
218-
return <Block key={key} {...props} value={props.node} renderNode={renderNode} />
219-
}
220-
221199
function renderText(node: ToolkitTextNode, key: string) {
222200
if (node.text === '\n') {
223201
const HardBreak = components.hardBreak
@@ -259,6 +237,86 @@ function getNodeRenderer (
259237
return renderNode
260238
}
261239

240+
241+
242+
function RenderBlock({
243+
renderNode,
244+
components,
245+
handleMissingComponent,
246+
node,
247+
index,
248+
isInline,
249+
}: {
250+
renderNode: NodeRenderer
251+
components: PortableTextReactComponents
252+
handleMissingComponent: MissingComponentHandler
253+
node: PortableTextBlock
254+
index: number
255+
isInline: boolean
256+
}) {
257+
const {_key, ...props} = serializeBlock({
258+
node,
259+
index,
260+
isInline,
261+
renderNode,
262+
})
263+
const style = props.node.style || 'normal'
264+
const handler =
265+
typeof components.block === 'function' ? components.block : components.block[style]
266+
const Block = handler || components.unknownBlockStyle
267+
268+
if (Block === components.unknownBlockStyle) {
269+
handleMissingComponent(unknownBlockStyleWarning(style), {
270+
nodeType: 'blockStyle',
271+
type: style,
272+
})
273+
}
274+
275+
return <Block {...props} value={props.node} renderNode={renderNode} />
276+
}
277+
278+
function RenderSpan({
279+
renderNode,
280+
components,
281+
handleMissingComponent,
282+
node,
283+
}: {
284+
renderNode: NodeRenderer
285+
components: PortableTextReactComponents
286+
handleMissingComponent: MissingComponentHandler
287+
node: ToolkitNestedPortableTextSpan
288+
}) {
289+
const {markDef, markType, markKey} = node
290+
const Span = components.marks[markType] || components.unknownMark
291+
const children = node.children.map((child, childIndex) =>
292+
renderNode({
293+
node: child,
294+
index: childIndex,
295+
isInline: true,
296+
renderNode,
297+
}),
298+
)
299+
300+
if (Span === components.unknownMark) {
301+
handleMissingComponent(unknownMarkWarning(markType), {
302+
nodeType: 'mark',
303+
type: markType,
304+
})
305+
}
306+
307+
return (
308+
<Span
309+
text={spanToPlainText(node)}
310+
value={markDef}
311+
markType={markType}
312+
markKey={markKey}
313+
renderNode={renderNode}
314+
>
315+
{children}
316+
</Span>
317+
)
318+
}
319+
262320
function serializeBlock(options: Serializable<PortableTextBlock>): SerializedBlock {
263321
const {node, index, isInline, renderNode} = options
264322
const tree = buildMarksTree(node)

0 commit comments

Comments
 (0)