Skip to content

Hooks Primitive

Types Primitives

A collection of hooks for core primitives.

Hooks

  • useComposedRefs Composes multiple refs into a single ref callback.
  • useControllableState Allows defaulting to an uncontrolled state and allows controlling the state from the parent.
  • useRelativePosition Returns a style for an element relative to another element.

Install the component via your command line.

Terminal window
npx expo install @rn-primitives/hooks
import * as React from 'react';
import { Pressable } from 'react-native';
import { useComposedRefs } from '@rn-primitives/hooks';
import type { PressableRef, SlottablePressableProps } from '@rn-primitives/types';
type ThingProps = SlottablePressableProps & React.RefAttributes<PressableRef>;
function Thing({ ref, ...props }: ThingProps) {
const localRef = React.useRef<PressableRef>(null);
const composedRef = useComposedRefs(ref, localRef);
React.useEffect(() => {
if (localRef.current) {
// Do something with the local ref
}
}, []);
return <Pressable ref={composedRef} {...props} />;
}
import * as React from 'react';
import { Pressable } from 'react-native';
import { useControllableState } from '@rn-primitives/hooks';
import type { PressableRef, SlottablePressableProps } from '@rn-primitives/types';
type ThingProps = SlottablePressableProps &
React.RefAttributes<PressableRef> & {
defaultOpen?: boolean;
open?: boolean;
onOpenChange?: (open: boolean) => void;
};
function Thing({
defaultOpen,
open: openProp,
onOpenChange: onOpenChangeProp,
onPress: onPressProp,
ref,
...props
}: ThingProps) {
const [open = false, onOpenChange] = useControllableState({
prop: openProp,
defaultProp: defaultOpen,
onChange: onOpenChangeProp,
});
function onPress() {
onOpenChange(!open);
onPressProp?.();
}
return <Pressable ref={ref} onPress={onPress} {...props} />;
}
import * as React from 'react';
import { View, type LayoutChangeEvent } from 'react-native';
import { useRelativePosition } from '@rn-primitives/hooks';
import type { PositionedContentProps, SlottableViewProps, ViewRef } from '@rn-primitives/types';
type ContentProps = SlottableViewProps & PositionedContentProps & React.RefAttributes<ViewRef>;
function Content({
align = 'center',
side = 'top',
sideOffset = 0,
alignOffset = 0,
avoidCollisions = true,
onLayout: onLayoutProp,
insets,
style,
disablePositioningStyle,
ref,
...props
}: ContentProps) {
const { contentLayout, setContentLayout, triggerPosition } = useRootContext();
const positionStyle = useRelativePosition({
align,
avoidCollisions,
triggerPosition,
contentLayout,
alignOffset,
insets,
sideOffset,
side,
disablePositioningStyle,
});
function onLayout(event: LayoutChangeEvent) {
setContentLayout(event.nativeEvent.layout);
onLayoutProp?.(event);
}
return <View ref={ref} style={[positionStyle, style]} onLayout={onLayout} {...props} />;
}
PropTypeNote
refs*Array<React.Ref<T> | undefined>Refs that should be composed into one callback
PropTypeNote
propT | undefined(optional)
defaultPropT | undefined(optional)
onChange(state: T | undefined) => void(optional)
PropTypeNote
align*‘start’ | ‘center’ | ‘end’Horizontal alignment of content position relative to trigger
avoidCollisions*booleanPrevent content from going offscreen
triggerPosition*LayoutPosition | nullLayout position of the trigger
contentLayout*LayoutRectangle | nullLayout Size of the content
alignOffset*numberHorizontal offset
insets*LayoutRectangleWhen avoidCollisions is true, it prevents content from going over insets
sideOffset*numberVertical offset
side*‘top’ | ‘bottom’;Side alignment of content position relative to trigger
disablePositioningStyle*booleanCompletely disables styling returned from hook