react-dom#flushSync TypeScript Examples
The following examples show how to use
react-dom#flushSync.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: ui-jsx.test-utils.tsx From utopia with MIT License | 5 votes |
export async function renderTestEditorWithModel(
model: PersistentModel,
awaitFirstDomReport: 'await-first-dom-report' | 'dont-await-first-dom-report',
mockBuiltInDependencies?: BuiltInDependencies,
): Promise<{
dispatch: (actions: ReadonlyArray<EditorAction>, waitForDOMReport: boolean) => Promise<void>
getDispatchFollowUpActionsFinished: () => Promise<void>
getEditorState: () => EditorStorePatched
renderedDOM: RenderResult
getNumberOfCommits: () => number
getNumberOfRenders: () => number
clearRecordedActions: () => void
getRecordedActions: () => ReadonlyArray<EditorAction>
}> {
const renderCountBaseline = renderCount
let recordedActions: Array<EditorAction> = []
let emptyEditorState = createEditorState(NO_OP)
const derivedState = deriveState(emptyEditorState, null)
const history = History.init(emptyEditorState, derivedState)
let editorDispatchPromises: Array<Promise<void>> = []
async function getDispatchFollowUpActionsFinished(): Promise<void> {
return Promise.all(editorDispatchPromises).then(NO_OP)
}
let workingEditorState: EditorStoreFull
const spyCollector = emptyUiJsxCanvasContextData()
// Reset canvas globals
resetDispatchGlobals()
clearAllRegisteredControls()
clearListOfEvaluatedFiles()
const asyncTestDispatch = async (
actions: ReadonlyArray<EditorAction>,
priority?: DispatchPriority, // priority is not used in the editorDispatch now, but we didn't delete this param yet
waitForDispatchEntireUpdate = false,
) => {
recordedActions.push(...actions)
const result = editorDispatch(asyncTestDispatch, actions, workingEditorState, spyCollector)
editorDispatchPromises.push(result.entireUpdateFinished)
invalidateDomWalkerIfNecessary(
domWalkerMutableState,
workingEditorState.patchedEditor,
result.patchedEditor,
)
workingEditorState = result
if (waitForDispatchEntireUpdate) {
await Utils.timeLimitPromise(
getDispatchFollowUpActionsFinished(),
2000,
'Follow up actions took too long.',
)
}
flushSync(() => {
canvasStoreHook.setState(patchedStoreFromFullStore(workingEditorState))
})
// run dom walker
const domWalkerResult = runDomWalker({
domWalkerMutableState: domWalkerMutableState,
selectedViews: workingEditorState.patchedEditor.selectedViews,
elementsToFocusOn: workingEditorState.patchedEditor.canvas.elementsToRerender,
scale: workingEditorState.patchedEditor.canvas.scale,
additionalElementsToUpdate:
workingEditorState.patchedEditor.canvas.domWalkerAdditionalElementsToUpdate,
rootMetadataInStateRef: {
current: Object.values(workingEditorState.patchedEditor.domMetadata),
},
})
if (domWalkerResult != null) {
const saveDomReportAction = saveDOMReport(
domWalkerResult.metadata,
domWalkerResult.cachedPaths,
domWalkerResult.invalidatedPaths,
)
recordedActions.push(saveDomReportAction)
const editorWithNewMetadata = editorDispatch(
asyncTestDispatch,
[saveDomReportAction],
workingEditorState,
spyCollector,
)
workingEditorState = editorWithNewMetadata
}
// update state with new metadata
flushSync(() => {
storeHook.setState(patchedStoreFromFullStore(workingEditorState))
if (shouldInspectorUpdate(workingEditorState.strategyState)) {
inspectorStoreHook.setState(patchedStoreFromFullStore(workingEditorState))
}
})
}
const workers = new UtopiaTsWorkersImplementation(
new FakeParserPrinterWorker(),
new FakeLinterWorker(),
new FakeWatchdogWorker(),
)
const builtInDependencies =
mockBuiltInDependencies != null
? mockBuiltInDependencies
: createBuiltInDependenciesList(workers)
const initialEditorStore: EditorStoreFull = {
strategyState: createEmptyStrategyState({}, {}),
unpatchedEditor: emptyEditorState,
patchedEditor: emptyEditorState,
unpatchedDerived: derivedState,
patchedDerived: derivedState,
history: history,
userState: {
loginState: notLoggedIn,
shortcutConfig: {},
},
workers: workers,
persistence: DummyPersistenceMachine,
dispatch: asyncTestDispatch,
alreadySaved: false,
builtInDependencies: builtInDependencies,
}
const canvasStoreHook = create<
EditorStorePatched,
SetState<EditorStorePatched>,
GetState<EditorStorePatched>,
Mutate<StoreApi<EditorStorePatched>, [['zustand/subscribeWithSelector', never]]>
>(subscribeWithSelector((set) => patchedStoreFromFullStore(initialEditorStore)))
const domWalkerMutableState = createDomWalkerMutableState(canvasStoreHook)
const inspectorStoreHook = create<
EditorStorePatched,
SetState<EditorStorePatched>,
GetState<EditorStorePatched>,
Mutate<StoreApi<EditorStorePatched>, [['zustand/subscribeWithSelector', never]]>
>(subscribeWithSelector((set) => patchedStoreFromFullStore(initialEditorStore)))
const storeHook = create<
EditorStorePatched,
SetState<EditorStorePatched>,
GetState<EditorStorePatched>,
Mutate<StoreApi<EditorStorePatched>, [['zustand/subscribeWithSelector', never]]>
>(subscribeWithSelector((set) => patchedStoreFromFullStore(initialEditorStore)))
// initializing the local editor state
workingEditorState = initialEditorStore
let numberOfCommits = 0
const result = render(
<React.Profiler
id='editor-root'
/* eslint-disable-next-line react/jsx-no-bind */
onRender={(id, phase, actualDuration, baseDuration, startTime, commitTime, interactions) => {
numberOfCommits++
}}
>
<FailJestOnCanvasError />
<EditorRoot
api={storeHook}
useStore={storeHook}
canvasStore={canvasStoreHook}
spyCollector={spyCollector}
inspectorStore={inspectorStoreHook}
domWalkerMutableState={domWalkerMutableState}
/>
</React.Profiler>,
{ legacyRoot: true },
)
await act(async () => {
await new Promise<void>((resolve, reject) => {
load(
async (actions) => {
try {
await asyncTestDispatch(actions, undefined, true)
resolve()
} catch (e) {
reject(e)
}
},
model,
'Test',
'0',
initialEditorStore.builtInDependencies,
false,
)
})
})
await act(async () => {
await asyncTestDispatch(
[switchEditorMode(EditorModes.selectMode()), setPanelVisibility('codeEditor', false)],
undefined,
true,
)
})
return {
dispatch: async (actions: ReadonlyArray<EditorAction>, waitForDOMReport: boolean) => {
return await act(async () => {
await asyncTestDispatch(actions, 'everyone', true)
})
},
getDispatchFollowUpActionsFinished: getDispatchFollowUpActionsFinished,
getEditorState: () => storeHook.getState(),
renderedDOM: result,
getNumberOfCommits: () => numberOfCommits,
getNumberOfRenders: () => renderCount - renderCountBaseline,
clearRecordedActions: () => {
recordedActions = []
},
getRecordedActions: () => recordedActions,
}
}
Example #2
Source File: use-collapse.ts From mantine with MIT License | 4 votes |
export function useCollapse({
transitionDuration,
transitionTimingFunction = 'ease',
onTransitionEnd = () => {},
opened,
}: UseCollapse): (props: GetCollapseProps) => Record<string, any> {
const el = useRef<HTMLElement | null>(null);
const collapsedHeight = '0px';
const collapsedStyles = {
display: 'none',
height: '0px',
overflow: 'hidden',
};
const [styles, setStylesRaw] = useState<React.CSSProperties>(opened ? {} : collapsedStyles);
const setStyles = (newStyles: {} | ((oldStyles: {}) => {})): void => {
flushSync(() => setStylesRaw(newStyles));
};
const mergeStyles = (newStyles: {}): void => {
setStyles((oldStyles) => ({ ...oldStyles, ...newStyles }));
};
function getTransitionStyles(height: number | string): {
transition: string;
} {
const _duration = transitionDuration || getAutoHeightDuration(height);
return {
transition: `height ${_duration}ms ${transitionTimingFunction}`,
};
}
useDidUpdate(() => {
if (opened) {
raf(() => {
mergeStyles({ willChange: 'height', display: 'block', overflow: 'hidden' });
raf(() => {
const height = getElementHeight(el);
mergeStyles({ ...getTransitionStyles(height), height });
});
});
} else {
raf(() => {
const height = getElementHeight(el);
mergeStyles({ ...getTransitionStyles(height), willChange: 'height', height });
raf(() => mergeStyles({ height: collapsedHeight, overflow: 'hidden' }));
});
}
}, [opened]);
const handleTransitionEnd = (e: React.TransitionEvent): void => {
if (e.target !== el.current || e.propertyName !== 'height') {
return;
}
if (opened) {
const height = getElementHeight(el);
if (height === styles.height) {
setStyles({});
} else {
mergeStyles({ height });
}
onTransitionEnd();
} else if (styles.height === collapsedHeight) {
setStyles(collapsedStyles);
onTransitionEnd();
}
};
function getCollapseProps({ style = {}, refKey = 'ref', ...rest }: GetCollapseProps = {}) {
const theirRef: any = rest[refKey];
return {
'aria-hidden': !opened,
...rest,
[refKey]: useMergedRef(el, theirRef),
onTransitionEnd: handleTransitionEnd,
style: { boxSizing: 'border-box', ...style, ...styles },
};
}
return getCollapseProps;
}