@react-three/flex Documentation

repository·master·Indexed 23 days ago

https://github.com/pmndrs/react-three-flex

A library that brings the web's Flexbox layout specification to react-three-fiber using the Yoga layout engine. It provides <Flex /> and <Box /> components to create complex 3D layouts with familiar CSS-like properties such as flexDirection, justifyContent, and alignItems, along with hooks like useFlexSize, useReflow, and useSyncGeometrySize for managing 3D layout dimensions and synchronization.

Tokens
4.3K
Snippets
8
Records
30
Agent score
83%

What's inside @react-three/flex

  1. How Invalidation and Reflow work

    master

    Layout calculations do not run every frame for performance reasons. A reflow (recalculation) is automatically triggered when:

    • <Flex /> props change (e.g., alignItems, size).
    • <Box /> props change (e.g., flexGrow, margin).
    • <Flex /> or <Box /> rerenders due to children differences.

    Manual Reflow: If you change object properties via useFrame, react-spring, or if a <Box /> is not rerendering because it is defined in a parent component, you must manually trigger a reflow using the useReflow() hook.

    // Manual reflow with useFrame
    function AnimatedBox() {
      const ref = useRef()
      const reflow = useReflow()
      useFrame(({ clock }) => {
        ref.current.scale.x = 1 + Math.sin(clock.getElapsed())
        reflow()
      })
      return (
        <Box centerAnchor>
          <mesh ref={ref}>
            <boxBufferGeometry attach="geometry" args={[10, 10, 10]} />
          </mesh>
        </Box>
      )
    }
    
    // Manual reflow with useEffect (when Box is outside the component)
    function AnimatedBox() {
      const [state, setState] = useState(true)
      const reflow = useReflow()
      useEffect(reflow, [state])
      return (
        <mesh scale={[state ? 1 : 3, 1, 1]}>
          <boxBufferGeometry attach="geometry" />
        </mesh>
      )
    }
  2. How Anchors work with centerAnchor

    master

    Yoga Layout (the underlying engine) expects object positions to be relative to the upper-left corner, similar to the DOM. However, most THREE.js geometries are positioned relative to their center. To align THREE.js objects correctly within the flex layout, set the centerAnchor prop to true on the <Box /> component.

    Note: If you are nesting <Box /> elements, you should set centerAnchor to false on the nested boxes.

    <Box centerAnchor>
      <mesh geometry={sphere} />
    </Box>
  3. How to stretch content using Box size

    master

    Since @react-three/flex only controls position by default, you must manually handle sizing if you want elements to stretch. You can access the calculated container size in two ways:

    1. Children render function: Pass a function as children to <Box /> to receive width and height.
    2. useFlexSize hook: Use the hook inside a component. Important: The useFlexSize hook only works if the <Box /> is defined outside the component using the hook.
    // Method 1: Children render function
    <Flex>
      <Box width="auto" height="auto" flexGrow={1} centerAnchor>
        {(width, height) => <Plane args={[width, height]} />}
      </Box>
    </Flex>
    
    // Method 2: useFlexSize hook
    function Inner() {
      const [width, height] = useFlexSize()
      return <Plane args={[width, height]} />
    }
    
    function Outer() {
      return (
        <Flex>
          <Box width="auto" height="auto" flexGrow={1} centerAnchor>
            <Inner />
          </Box>
        </Flex>
      )
    }
  4. Eject from Create React App configuration

    master

    If you need full control over the underlying build configuration (webpack, Babel, ESLint, etc.), you can run yarn eject.

    Warning: This is a one-way operation. Once you eject, you cannot go back.

    Ejecting will remove the single build dependency and copy all configuration files and transitive dependencies directly into your project. After ejecting, you are responsible for managing these configurations.

    yarn eject
  5. Basic Usage of Flex and Box

    master

    Create layouts by wrapping 3D objects in <Box /> instances inside a <Flex /> container. The <Flex /> container manages the layout of its children, and <Box /> components act as the flex items. You can use standard CSS flex properties like flexDirection or justifyContent on the container, and flexGrow on the boxes.

    import { Flex, Box } from '@react-three/flex'
    
    const Layout = () => (
      <Flex justifyContent="center" alignItems="center">
        <Box centerAnchor>
          <mesh geometry={box} />
        </Box>
        <Box centerAnchor flexGrow={1}>
          <mesh geometry={torus} />
        </Box>
      </Flex>
    )
  6. Configure Flex container sizing and axis orientation

    master

    Unlike DOM Flexbox, @react-three/flex requires a defined size for the root <Flex /> container to be responsive.

    Axis Orientation: You must specify the 3D plane the flex layout lives on using the plane prop. The default is xy. Other options are yz and xz. The size prop values correspond to the axes chosen (e.g., if plane="xy", size={[width, height, depth]} uses the first two values for layout).

    Scale Factor: The engine uses integers for precision. It multiplies sizes by scaleFactor (default 100). If your scene scale is significantly different, adjust this prop.

  7. Run the examples project

    master

    The examples directory is a Create React App project. You can manage the development lifecycle using the following commands:

    • Development: Run yarn start to launch the app in development mode at http://localhost:3000. The page will reload on edits.
    • Testing: Run yarn test to launch the test runner in interactive watch mode.
    • Production Build: Run yarn build to create an optimized, minified production build in the build folder.
    yarn start
    yarn test
    yarn build
  8. Use Margin and Padding

    master

    Both <Flex /> and <Box /> components support margin and padding props, similar to CSS.

    <Flex flexDirection="row" size={[300, 200, 0]} padding={30} margin={5}>
      <Box padding={5} marginTop={5} centerAnchor>
        <mesh geometry={sphere} />
      </Box>
    </Flex>
  9. Measure container size with onReflow

    master
    To synchronize the 3D Flex container with the DOM (e.g., for scroll synchronization), use the onReflow prop on the <Flex /> component. This callback is executed every time the layout is recalculated.
  10. Use the Box component for layout containers

    master

    The Box component is the fundamental building block of the react-three-flex system. It acts as a container for 3D objects and uses Yoga (a flexbox engine) to manage layout.

    Key Features:

    • Flexbox Props: Supports standard flexbox properties like flexDirection, alignItems, justifyContent, flexGrow, margin, and padding via shorthand or longhand names.
    • Sizing: Supports width, height, minWidth, maxWidth, minHeight, and maxHeight.
    • Render Prop for Children: The children prop can be a function that receives the computed width, height, and centerAnchor status. This allows children to react to the layout size calculated by the flex engine.
    • Center Anchor: The centerAnchor prop (boolean) determines how the content is anchored within the box.

    Note: For a container that manages multiple children using flexbox rules, use the <Flex /> component instead of <Box />.