Skip to content

Commit

Permalink
feat(react-multipsass-rendering): custom react dispatcher to support …
Browse files Browse the repository at this point in the history
…some hooks in a staticRender
  • Loading branch information
matej21 committed Mar 4, 2024
1 parent 0e23dbc commit bcda20b
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 10 deletions.
4 changes: 3 additions & 1 deletion build/api/react-multipass-rendering.api.md
Expand Up @@ -6,7 +6,7 @@

import type { ElementType } from 'react';
import type { ReactElement } from 'react';
import type { ReactNode } from 'react';
import { ReactNode } from 'react';
import type { ReactText } from 'react';

// @public (undocumented)
Expand Down Expand Up @@ -48,6 +48,8 @@ export class ChildrenAnalyzer<AllLeavesRepresentation = any, AllBranchNodesRepre
// Warning: (ae-forgotten-export) The symbol "BranchNodeList" needs to be exported by the entry point index.d.ts
constructor(leaves: LeafList<AllLeavesRepresentation, StaticContext>, branchNodes: BranchNodeList<AllLeavesRepresentation, AllBranchNodesRepresentation, StaticContext>, options?: Partial<ChildrenAnalyzerOptions>);
// (undocumented)
doProcessChildren(children: ReactNode, initialStaticContext: StaticContext): Array<AllLeavesRepresentation | AllBranchNodesRepresentation>;
// (undocumented)
processChildren(children: ReactNode, initialStaticContext: StaticContext): Array<AllLeavesRepresentation | AllBranchNodesRepresentation>;
}

Expand Down
75 changes: 66 additions & 9 deletions packages/react-multipass-rendering/src/ChildrenAnalyzer.ts
@@ -1,5 +1,6 @@
import { assertNever } from '@contember/utilities'
import type { ElementType, ReactElement, ReactNode } from 'react'
import { ElementType, ReactElement, ReactNode, useReducer } from 'react'
import * as React from 'react'
import type { BranchNodeList } from './BranchNodeList'
import { ChildrenAnalyzerError } from './ChildrenAnalyzerError'
import type { ChildrenAnalyzerOptions } from './ChildrenAnalyzerOptions'
Expand Down Expand Up @@ -66,17 +67,30 @@ export class ChildrenAnalyzer<
children: ReactNode,
initialStaticContext: StaticContext,
): Array<AllLeavesRepresentation | AllBranchNodesRepresentation> {
if ('__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED' in React) {
const { ReactCurrentDispatcher } = (React as any).__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED
const originalCurrentDispatcher = ReactCurrentDispatcher.current
ReactCurrentDispatcher.current = {
...originalCurrentDispatcher,
...staticRenderReactDispatcher,
}
const result = this.doProcessChildren(children, initialStaticContext)
ReactCurrentDispatcher.current = originalCurrentDispatcher
return result
}
return this.doProcessChildren(children, initialStaticContext)
}

public doProcessChildren(
children: ReactNode,
initialStaticContext: StaticContext,
): Array<AllLeavesRepresentation | AllBranchNodesRepresentation> {

const processed = this.processNode(children, initialStaticContext, [])

const rawResult: Array<AllLeavesRepresentation | AllBranchNodesRepresentation | undefined> = Array.isArray(
processed,
)
? processed
: [processed]
const rawResult = Array.isArray(processed) ? processed : [processed]

return rawResult.filter(
(item): item is AllLeavesRepresentation | AllBranchNodesRepresentation => item !== undefined,
)
return rawResult.filter((item): item is AllLeavesRepresentation | AllBranchNodesRepresentation => item !== undefined)
}

private processNode(
Expand Down Expand Up @@ -258,3 +272,46 @@ export class ChildrenAnalyzer<
return processedChildren
}
}

let id = 0
const staticRenderReactDispatcher = {
useCallback: (cb: any) => {
return cb
},
useDebugValue: () => {
// do nothing
},
useEffect: () => {
// do nothing
},
useImperativeHandle: () => {
// do nothing
},
useLayoutEffect: () => {
// do nothing
},
useMemo: (value: () => any) => {
return value()
},
useReducer: (reducer: any, initializerArg: any, initializer: any) => {
return initializer ? [initializer(initializerArg), () => {
}] : [initializerArg, () => {
}]
},
useRef: (initialValue: any) => {
return { current: initialValue }
},
useState: (initialState: any) => {
return [typeof initialState === 'function' ? initialState() : initialState, () => {
}]
},
useDeferredValue: (value: any) => {
return value
},
useId() {
return `id-${id++}`
},
useInsertionEffect() {
// do nothing
},
}

0 comments on commit bcda20b

Please sign in to comment.