react#useLayoutEffect TypeScript Examples
The following examples show how to use
react#useLayoutEffect.
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: InlineDatePicker.tsx From ant-extensions with MIT License | 7 votes |
InlineDatePicker: React.FC<DatePickerProps> = React.forwardRef<
React.Component,
DatePickerProps
>((props, ref) => {
const refContainer = useRef<HTMLDivElement>(null);
const refPicker = useRef<HTMLDivElement>(document.createElement("div"));
useLayoutEffect(() => {
if (refContainer.current) {
refContainer.current.appendChild(refPicker.current);
}
}, []);
return (
<I18nextProvider i18n={i18next}>
<div ref={refContainer} className="ant-ext-sd__inlinePicker">
<DatePicker
{...props}
ref={ref}
open
inputReadOnly
getPopupContainer={() => refPicker.current}
/>
</div>
</I18nextProvider>
);
})
Example #2
Source File: utils.ts From erda-ui with GNU Affero General Public License v3.0 | 7 votes |
export function useSmartTooltip({ mouseX, mouseY }: { mouseX: number; mouseY: number }) {
const ref = useRef<HTMLDivElement>(null);
useLayoutEffect(() => {
const element = ref.current;
if (element != null) {
if (mouseY + TOOLTIP_OFFSET + element?.offsetHeight >= window.innerHeight) {
if (mouseY - TOOLTIP_OFFSET - element.offsetHeight > 0) {
element.style.top = `${mouseY - element.offsetHeight - TOOLTIP_OFFSET}px`;
} else {
element.style.top = '0px';
}
} else {
element.style.top = `${mouseY + TOOLTIP_OFFSET}px`;
}
if (mouseX + TOOLTIP_OFFSET + element.offsetWidth >= window.innerWidth) {
if (mouseX - TOOLTIP_OFFSET - element.offsetWidth > 0) {
element.style.left = `${mouseX - element.offsetWidth - TOOLTIP_OFFSET}px`;
} else {
element.style.left = '0px';
}
} else {
element.style.left = `${mouseX + TOOLTIP_OFFSET}px`;
}
}
});
return ref;
}
Example #3
Source File: useWindowSize.tsx From firecms with MIT License | 6 votes |
export function useWindowSize(): WindowSize {
const [size, setSize] = useState<WindowSize>({ width: 0, height: 0 });
useLayoutEffect(() => {
function updateSize() {
setSize({ width: window.innerWidth, height: window.innerHeight });
}
window.addEventListener("resize", updateSize);
updateSize();
return () => window.removeEventListener("resize", updateSize);
}, []);
return size;
}
Example #4
Source File: XarrowV2.stories.tsx From react-xarrows with MIT License | 6 votes |
useParseProps = (props: MyComponentPropsType) => {
const [parsedVals, setParsedVals] = useState({ parsedProp1: parseVal1(MyComponentDefaultProps.prop1) });
useLayoutEffect(() => {
parsedVals.parsedProp1 = parseVal1(props.prop1);
setParsedVals({ ...parsedVals });
}, [props.prop1]);
return parsedVals;
}
Example #5
Source File: checkboxColumn.tsx From react-datasheet-grid with MIT License | 6 votes |
CheckboxComponent = React.memo<CellProps<boolean, any>>(
({ focus, rowData, setRowData, active, stopEditing }) => {
const ref = useRef<HTMLInputElement>(null)
// When cell becomes focus we immediately toggle the checkbox and blur the cell by calling `stopEditing`
// Notice the `nextRow: false` to make sure the active cell does not go to the cell below and stays on this cell
// This way the user can keep pressing Enter to toggle the checkbox on and off multiple times
useLayoutEffect(() => {
if (focus) {
setRowData(!rowData)
stopEditing({ nextRow: false })
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [focus, stopEditing])
return (
<input
className="dsg-checkbox"
// Important to prevent any undesired "tabbing"
tabIndex={-1}
type="checkbox"
ref={ref}
checked={Boolean(rowData)}
// When cell is not active, we allow the user to toggle the checkbox by clicking on it
// When cell becomes active, we disable this feature and rely on focus instead (see `useLayoutEffect` above)
onMouseDown={() => !active && setRowData(!rowData)}
onChange={() => null}
/>
)
}
)
Example #6
Source File: Tag.tsx From frontend with GNU General Public License v3.0 | 6 votes |
Tag = ({ children, bgColor, fontColor, getWidth, ...props }: IProps): JSX.Element => {
const elementsRef = useRef<HTMLDivElement>(null);
const getWidthAfterDOMLoad = useCallback(() => {
getWidth(elementsRef.current?.getBoundingClientRect().width || 0);
}, [getWidth]);
useLayoutEffect(() => {
window.addEventListener('load', getWidthAfterDOMLoad);
}, [getWidthAfterDOMLoad]);
return (
<TagElement ref={elementsRef} bgColor={bgColor} fontColor={fontColor} {...props}>
{children}
</TagElement>
);
}
Example #7
Source File: useWindowSize.ts From taskcafe with MIT License | 6 votes |
export default function useWindowSize() {
const [size, setSize] = useState([0, 0]);
useLayoutEffect(() => {
function updateSize() {
setSize([window.innerWidth, window.innerHeight]);
}
window.addEventListener('resize', updateSize);
updateSize();
return () => window.removeEventListener('resize', updateSize);
}, []);
return size;
}
Example #8
Source File: Glider.tsx From atlas with GNU General Public License v3.0 | 6 votes |
function useEventListener<K extends keyof GliderEventMap>(
element: HTMLElement | undefined | null,
event: K,
// eslint-disable-next-line @typescript-eslint/no-empty-function
listener: (event: GliderEvent<GliderEventMap[K]>) => void = () => {}
) {
const savedListener = useRef(listener)
useEffect(() => {
savedListener.current = listener
}, [listener])
useLayoutEffect(() => {
if (!element) {
return
}
element.addEventListener(event, savedListener.current)
return () => {
element.removeEventListener(event, savedListener.current)
}
}, [event, element])
}
Example #9
Source File: VirtualTableHeader.tsx From posthog-foss with MIT License | 6 votes |
function VirtualTableHeader<RecordType>({
columns,
handleResize,
layoutEffect,
minColumnWidth: defaultMinColumnWidth,
expandable,
}: VirtualTableHeaderProps<RecordType>): JSX.Element {
const height = 60
useLayoutEffect(() => (typeof layoutEffect === 'function' ? layoutEffect() : undefined))
return (
<div className="resizable-virtual-table-header">
{!!expandable && (
<div className="left-spacer" style={{ width: expandable?.columnWidth || ANTD_EXPAND_BUTTON_WIDTH }} />
)}
{columns.map(({ title, width, widthConstraints }, index) => {
const minColumnWidth = widthConstraints?.length ? widthConstraints[0] : defaultMinColumnWidth
const maxColumnWidth = widthConstraints?.length ? widthConstraints[1] : Infinity
return (
<ResizableTitle
key={index}
initialWidth={width ?? minColumnWidth}
height={height}
onResize={handleResize(index)}
minConstraints={[minColumnWidth, height]}
maxConstraints={[maxColumnWidth, height]}
>
{title}
</ResizableTitle>
)
})}
</div>
)
}
Example #10
Source File: index.ts From react-carousel with MIT License | 6 votes |
useWindowWidthChange = (callBack: (changed: number) => any) => {
const [windowWidth, setWindowWidth] = useState(getWindowWidth());
useLayoutEffect(() => {
const update = () => {
const changed = windowWidth - window.innerWidth;
setWindowWidth(window.innerWidth);
callBack(changed);
};
window.addEventListener('resize', update);
return () => window.removeEventListener('resize', update);
}, []);
return;
}
Example #11
Source File: useColor.ts From sybil-interface with GNU General Public License v3.0 | 6 votes |
export function useColor(token?: Token) {
const [color, setColor] = useState('#2172E5')
useLayoutEffect(() => {
let stale = false
if (token) {
getColorFromToken(token).then((tokenColor) => {
if (!stale && tokenColor !== null) {
setColor(tokenColor)
}
})
}
return () => {
stale = true
setColor('#2172E5')
}
}, [token])
return color
}
Example #12
Source File: Aside.tsx From ant-extensions with MIT License | 6 votes |
Aside: React.FC = React.memo(() => {
const { t } = useTranslation(I18nKey);
const { selected, editConfig } = useContext(Context);
const [active, setActive] = useState<string | string[]>(["widgets"]);
useLayoutEffect(() => {
setActive(selected ? ["config", "widgets"] : ["widgets"]);
}, [selected]);
return (
<div className="ant-ext-pm__aside">
<Collapse activeKey={active}>
{selected && (
<Collapse.Panel
key="config"
showArrow={false}
header={t("label.config")}
extra={<CloseOutlined onClick={() => editConfig(undefined)} />}
>
<Config />
</Collapse.Panel>
)}
<Collapse.Panel showArrow={false} key="widgets" header={t("label.widgets")}>
<WidgetList />
</Collapse.Panel>
</Collapse>
</div>
);
})
Example #13
Source File: ColorPicker.tsx From animation-editor with MIT License | 6 votes |
Strip: React.FC<{ hue: number; onHueChange: (hue: number) => void }> = (props) => { const canvas = useRef<HTMLCanvasElement>(null); const ctx = useRef<CanvasRenderingContext2D | null>(null); const [y, setY] = useState(() => Math.round((props.hue / 360) * HEIGHT)); useLayoutEffect(() => { ctx.current = canvas.current?.getContext("2d") || null; }, [canvas.current]); // Render strip once on mount useLayoutEffect(() => { if (!ctx.current) { return; } for (let i = 0; i < HEIGHT; i += 1) { ctx.current.fillStyle = `hsl(${(i / HEIGHT) * 360}, 100%, 50%)`; ctx.current.fillRect(0, i, STRIP_WIDTH, 1); } }, [ctx.current]); const pixelSelector = useCanvasPixelSelector( canvas, { allowOutside: true }, (rgbColor, position) => { const [hue] = rgbToHSL(rgbColor); props.onHueChange(hue); setY(position.y); }, ); return ( <div style={{ position: "relative", marginRight: 16 }}> <canvas ref={canvas} height={HEIGHT} width={STRIP_WIDTH} {...pixelSelector} /> <div style={{ top: y }} className={s("hueCursor")} /> </div> ); }
Example #14
Source File: index.ts From ChatUI with MIT License | 6 votes |
Portal: React.FC<PortalProps> = (props) => {
const { children, container = document.body, onRendered } = props;
const [mountNode, setMountNode] = useState<Element | null>(null);
useEffect(() => {
setMountNode(getEl(container));
}, [container]);
useLayoutEffect(() => {
if (onRendered && mountNode) {
onRendered();
}
}, [mountNode, onRendered]);
return mountNode ? createPortal(children, mountNode) : mountNode;
}
Example #15
Source File: useOverflowWrapper.ts From hub with Apache License 2.0 | 6 votes |
useOverflowWrapper = (
wrapperRef: MutableRefObject<HTMLDivElement | null>,
maxHeight: number,
itemsLength: number
) => {
const getHeight = (): number => {
if (wrapperRef && wrapperRef.current) {
return wrapperRef.current.offsetHeight;
} else {
return 0;
}
};
const checkDimensions = () => {
const height = getHeight();
return height > maxHeight;
};
const [overflowContainer, setOverflowContainer] = useState<boolean>(() => checkDimensions());
const handleOverflow = () => {
setOverflowContainer(checkDimensions());
};
useEffect(() => {
window.addEventListener('resize', throttle(handleOverflow, 200));
return () => window.removeEventListener('resize', handleOverflow);
}, []); /* eslint-disable-line react-hooks/exhaustive-deps */
useLayoutEffect(() => {
handleOverflow();
}, []); /* eslint-disable-line react-hooks/exhaustive-deps */
useEffect(() => {
handleOverflow();
}, [itemsLength]); /* eslint-disable-line react-hooks/exhaustive-deps */
return overflowContainer;
}
Example #16
Source File: render.tsx From react-loosely-lazy with Apache License 2.0 | 6 votes |
usePlaceholderRender = (resolveId: string, content: HTMLElement[]) => {
const hydrationRef = useRef<HTMLInputElement | null>(null);
const { current: ssrDomNodes } = useRef(content || ([] as HTMLElement[]));
useLayoutEffect(() => {
const element = hydrationRef.current;
const { parentNode } = element || {};
if (parentNode && !parentNode.contains(ssrDomNodes[0])) {
ssrDomNodes.reverse().forEach((node: HTMLElement) => {
// this fixes an issue with Chrome that re-triggers and cancels prefetch
// when node is appended again, making network panel quite noisy
if (isLinkPrefetch(node)) node.rel = '';
parentNode.insertBefore(node, (element as any).nextSibling);
});
}
return () => {
ssrDomNodes.forEach((node: HTMLElement) =>
node.parentNode?.removeChild(node)
);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [hydrationRef.current, ssrDomNodes]);
return hydrationRef;
}
Example #17
Source File: Hits.tsx From checklist with MIT License | 6 votes |
Hits: FC<Props & HitsProvided<ChecklistHit>> = ({ hits, onClick }) => {
const enterListener = (event: KeyboardEvent) => {
if (event.key === 'Enter' && hits.length > 0) {
navigate(`/checklist/${hits[0].slug}`);
}
};
useLayoutEffect(() => {
window.addEventListener('keyup', enterListener);
return () => {
window.removeEventListener('keyup', enterListener);
};
});
return (
<div className="c-search__hits">
{hits.map(hit => (
<SearchCard
key={hit.objectID}
category={hit.category}
categorySlug={hit.categorySlug}
todoCount={hit.todoCount}
title={hit.title}
description={hit.description}
tags={hit.tags}
slug={hit.slug}
onClick={onClick}
/>
))}
</div>
);
}
Example #18
Source File: useDynamicFontSize.tsx From amazon-chime-live-events with Apache License 2.0 | 6 votes |
useDynamicFontSize = (ref: RefObject<HTMLElement>) => {
const [fontSize, setFontSize] = useState<string>();
useLayoutEffect(() => {
if (!ref.current) {
return;
}
const { width } = ref.current.getBoundingClientRect();
setFontSize(getNamePlateFontSize(width));
}, []);
useEffect(() => {
const el = ref.current;
if (!el) {
return;
}
const handleResize = debounce(50, (entries: any) => {
const { width } = entries[0].contentRect;
setFontSize(getNamePlateFontSize(width));
});
const resizeObserver = new ResizeObserver(handleResize);
resizeObserver.observe(el);
return () => resizeObserver.unobserve(el);
}, []);
return fontSize;
}
Example #19
Source File: useElementAspectRatio.tsx From amazon-chime-sdk-smart-video-sending-demo with Apache License 2.0 | 6 votes |
useElementAspectRatio = (ref: RefObject<HTMLElement>): AspectRatio | null => {
const [ratio, setRatio] = useState<AspectRatio | null>(null);
useLayoutEffect(() => {
if (!ref.current) {
return;
}
const { height, width } = ref.current.getBoundingClientRect();
setRatio(getAspectRatio(height, width));
}, []);
useEffect(() => {
if (!ref.current) {
return;
}
const handleResize = debounce(50, (entries: any) => {
const { height, width } = entries[0].contentRect;
setRatio(getAspectRatio(height, width));
});
const resizeObserver = new ResizeObserver(handleResize);
resizeObserver.observe(ref.current);
return () => resizeObserver.disconnect();
}, []);
return ratio;
}
Example #20
Source File: use-initial.test.tsx From use-between with MIT License | 6 votes |
test('Should block effect hooks on server', () => {
const fn = jest.fn()
const fnA = jest.fn()
const fnB = jest.fn()
const fnC = jest.fn()
const useStore = () => {
useEffect(fnA, [])
useLayoutEffect(fnB, [])
useImperativeHandle(fnC, () => 10, [])
fn()
}
const A = () => {
useBetween(useStore)
return null
}
const B = () => {
useBetween(useStore)
return null
}
const C = () => {
useInitial(null, true)
return <><A /><B /></>
}
mount(<C/>)
expect(fn).toBeCalledTimes(1)
expect(fnA).toBeCalledTimes(0)
expect(fnB).toBeCalledTimes(0)
expect(fnC).toBeCalledTimes(0)
});
Example #21
Source File: useCombineRef.ts From fe-foundation with Apache License 2.0 | 6 votes |
export function useCombineRef<T>(...refs: Array<Ref<T> | undefined>): RefObject<T> {
const ref = useRef<T>(null);
// 每一次useLayoutEffect都同步,用useLayoutEffect来同步执行,以希望比useEffect更早
useLayoutEffect(() => {
refs.forEach(item => {
if (item == null) {
return;
}
if (typeof item === 'function') {
item(ref.current);
} else {
Object.assign(item, {current: ref.current});
}
});
});
return ref;
}
Example #22
Source File: useResizeObserver.ts From celo-web-wallet with MIT License | 6 votes |
useResizeObserver = () => {
const [observerEntry, setObserverEntry] = useState<ResizeObserverEntry | null>(null)
const [nodeRef, setNodeRef] = useState<Element | null>(null)
const observer = useRef<ResizeObserver | null>(null)
const disconnect = useCallback(() => observer.current?.disconnect(), [])
const observe = useCallback(() => {
observer.current = new ResizeObserver((entries: ResizeObserverEntry[]) => {
setObserverEntry(entries[0])
})
if (nodeRef) observer.current.observe(nodeRef)
}, [nodeRef])
useLayoutEffect(() => {
observe()
return () => disconnect()
}, [disconnect, observe])
return { setNodeRef, observerEntry }
}
Example #23
Source File: ChessBoard.tsx From platform with MIT License | 6 votes |
function PGNViewer(props) {
const { layout, size, mode="view" } = props;
const gameDescription = Children.onlyText(props.children);
const id = "board-" + uuid.v4();
useLayoutEffect(() => {
pgnView(id, {
pgn: gameDescription,
mode,
theme: "informator",
layout: layout,
hideMovesBefore: true,
locale: "en",
showResult: true,
boardSize: size,
showFen: false,
pieceStyle: "alpha",
});
});
return <div id={id}></div>;
}
Example #24
Source File: useComponentRegistry.ts From r3f-game-demo with MIT License | 6 votes |
export default function useComponentRegistry<T extends ComponentRef>(
name: T['name'],
api: T['api']
) {
const { registerComponent, unregisterComponent } = useGameObject();
useLayoutEffect(() => {
registerComponent<T>(name, api);
});
useLayoutEffect(() => {
return () => unregisterComponent<T>(name);
}, [unregisterComponent, name]);
return api;
}
Example #25
Source File: GameLandingPageComponents.tsx From client with GNU General Public License v3.0 | 6 votes |
export function TerminalToggler({
terminalEnabled,
setTerminalEnabled,
}: {
terminalEnabled: boolean;
setTerminalEnabled: Dispatch<SetStateAction<boolean>>;
}) {
const uiEmitter = UIEmitter.getInstance();
useLayoutEffect(() => {
uiEmitter.emit(UIEmitterEvent.UIChange);
}, [terminalEnabled, uiEmitter]);
return (
<StyledTerminalToggler
terminalEnabled={terminalEnabled}
onClick={() => setTerminalEnabled((b: boolean): boolean => !b)}
>
<span>{terminalEnabled ? '>' : '<'}</span>
</StyledTerminalToggler>
);
}
Example #26
Source File: XAxis.tsx From arduino-web-oscilloscope with MIT License | 6 votes |
export default function XAxis() {
const nodeRef = useRef<SVGSVGElement>(null)
const height = useRecoilValue(plotHeightSelector)
const xScale = useRecoilValue(xScaleSelector)
const gEl = nodeRef.current
useLayoutEffect(() => {
if (!gEl) return
const xTicks = d3.ticks(xScale.domain()[0], xScale.domain()[1], 10)
d3.select(gEl).call((g) =>
g
.attr('transform', `translate(0,${height - margin.bottom})`)
.call(
d3
.axisBottom(xScale)
.tickValues(xTicks)
.tickPadding(10)
.tickSize(-height + margin.top + margin.bottom)
.tickFormat(formatTime)
.tickSizeOuter(0)
)
.call((g) => g.select('.domain').remove())
)
}, [gEl, xScale, height])
return <g className="x axis" ref={nodeRef} />
}
Example #27
Source File: UpdateSW.tsx From nuzlocke with BSD 3-Clause "New" or "Revised" License | 6 votes |
function UpdateSW(): JSX.Element {
const [waitingServiceWorker, setWaitingServiceWorker] = useState(null);
const setServiceWorker = useCallback(
(registration: ServiceWorkerRegistration) => {
setWaitingServiceWorker(registration.waiting);
},
[setWaitingServiceWorker]
);
useLayoutEffect(() => {
window.setServiceWorker = setServiceWorker;
}, [setServiceWorker]);
const updateServiceWorker = () => {
if (waitingServiceWorker) {
waitingServiceWorker.postMessage({ type: 'SKIP_WAITING' });
// eslint-disable-next-line @typescript-eslint/no-explicit-any
waitingServiceWorker.addEventListener('statechange', (e: any) => {
if (e.target.state === 'activated') {
window.location.reload();
}
});
}
};
return waitingServiceWorker ? (
<div className={styles.alert}>
<span>New version available</span>
<Button color="grey" onClick={updateServiceWorker} type="button">
Update
</Button>
</div>
) : null;
}
Example #28
Source File: useColor.ts From dyp with Do What The F*ck You Want To Public License | 6 votes |
export function useColor(token?: Token) {
const [color, setColor] = useState('#2172E5')
useLayoutEffect(() => {
let stale = false
if (token) {
getColorFromToken(token).then(tokenColor => {
if (!stale && tokenColor !== null) {
setColor(tokenColor)
}
})
}
return () => {
stale = true
setColor('#2172E5')
}
}, [token])
return color
}
Example #29
Source File: usePortal.ts From ebs-design with MIT License | 6 votes |
usePortal = (id = 'portal') => {
const wrapperRef = useRef<HTMLElement | null>(document.getElementById(id));
if (wrapperRef.current === null && typeof document !== 'undefined') {
const div = document.createElement('div');
div.id = id;
wrapperRef.current = div;
}
useLayoutEffect(() => {
const wrapper = wrapperRef.current;
if (!wrapper || typeof document === 'undefined') {
return;
}
document.body.appendChild(wrapper);
}, []);
return (children) => wrapperRef.current && createPortal(children, wrapperRef.current);
}