> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bitfield.so/llms.txt
> Use this file to discover all available pages before exploring further.

# Read data in React

> Use useBitfieldData as the public React read surface for prepared Bitfield data.

<div className="bf-article">
  <p className="bf-lead">
    Use `useBitfieldData(...)` when a React component needs data that Runtime Kit has already prepared for that surface.
  </p>

  ## What this is

  `useBitfieldData(...)` is the public React read hook. It gives a component one consistent return shape:

  ```ts theme={null}
  {
    data: T | null;
    loading: boolean;
    error: Error | null;
  }
  ```

  That shape is the point. Your component can render data, loading, and error states without importing the code that prepared the data.

  ## The mental model

  The component asks for data by using the hook. Runtime Kit decides what data name that component is allowed to read. The component receives the latest app-facing value.

  This is not a normal fetch call. The component is not asking a server for a record by URL. It is reading a prepared app value. Runtime Kit may prepare that value from local data, package records, package-owned bytes, derived values, or another public package surface. The component should not import that preparation path.

  ## How it works technically

  ```text theme={null}
  package material becomes app-facing data
    -> Runtime Kit exposes a read input to this component tree
    -> useBitfieldData(...) selects the default input or a named input
    -> React receives { data, loading, error }
  ```

  The public hook call is stable even when Runtime Kit changes how it prepares the value.

  For the exact selector forms, return-state contract, and invalid examples, read [Runtime Kit API](/reference/runtime-kit-api).

  | Public concept | Meaning                                                         |
  | -------------- | --------------------------------------------------------------- |
  | Named data     | Data Runtime Kit has already made available to the app surface. |
  | Selector       | A public way to pick which data name you want.                  |
  | `data`         | The current materialized value, or `null` if none is ready.     |
  | `loading`      | `true` while Runtime Kit is preparing or waiting for the value. |
  | `error`        | An `Error` when the read surface cannot provide the value.      |

  ## Import

  ```ts theme={null}
  import { useBitfieldData } from '@bitfield/runtime-kit/react';
  ```

  Do not import from unpublished Runtime Kit paths. The public React package exports the hook.

  ## Read the default input

  Use the hook without an argument when the surface has one default prepared value.

  ```tsx theme={null}
  import { useBitfieldData } from '@bitfield/runtime-kit/react';

  type WelcomeData = {
    headline: string;
    body: string;
  };

  export function WelcomePanel() {
    const welcome = useBitfieldData<WelcomeData>();

    if (welcome.loading) return <section>Loading</section>;
    if (welcome.error) return <section>Could not load this panel.</section>;
    if (!welcome.data) return null;

    return (
      <section>
        <h2>{welcome.data.headline}</h2>
        <p>{welcome.data.body}</p>
      </section>
    );
  }
  ```

  ## Read a named input

  Use a string selector when the surface exposes more than one data name.

  ```tsx theme={null}
  const welcome = useBitfieldData<WelcomeData>('welcome');
  const profile = useBitfieldData<{ name: string }>('profile');
  ```

  The string is not a storage path. It is a public input name made available to this surface.

  ## Read with local params

  Some surfaces may allow a selection object with params. Params are local selection data, like the current search query or selected item id.

  ```tsx theme={null}
  const result = useBitfieldData<SearchResult>({
    input: 'search-results',
    params: { query },
  });
  ```

  Use params for the user selection on this screen. Do not use params to smuggle private storage or setup into a component.

  ## Render every state

  Good Runtime Kit components handle four states.

  ```tsx theme={null}
  if (store.loading) return <section>Loading</section>;
  if (store.error) return <section>{store.error.message}</section>;
  if (!store.data) return <section>No data yet</section>;
  return <section>{store.data.title}</section>;
  ```

  That sounds simple because it should be simple. Runtime Kit owns the preparation work.

  ## Pair it with a request

  Use the hook for reading. Use `sendRequestToBitfieldTarget(...)` when the user asks something to do work.

  ```tsx theme={null}
  import { sendRequestToBitfieldTarget } from '@bitfield/runtime-kit';
  import { useBitfieldData } from '@bitfield/runtime-kit/react';

  export function SearchBox() {
    const results = useBitfieldData<SearchResult[]>('search-results');

    async function runSearch(query: string) {
      await sendRequestToBitfieldTarget({
        target: 'product.search',
        payload: { query },
      });
    }

    return (
      <section>
        <button type="button" onClick={() => runSearch('blue jacket')}>
          Search
        </button>
        {results.data?.map((item) => <p key={item.id}>{item.name}</p>)}
      </section>
    );
  }
  ```

  The request asks a target to do work. The hook reads prepared results.

  ## Before / after

  | Before                                            | After                                                               |
  | ------------------------------------------------- | ------------------------------------------------------------------- |
  | Component imports storage helpers.                | Component imports one hook.                                         |
  | Component chooses low-level data wiring.          | Runtime Kit handles preparation behind the surface.                 |
  | Component imports package implementation details. | Component uses public input names and data shape.                   |
  | The component has many low-level APIs to misuse.  | The component gets one read shape and fewer ways to tangle the app. |

  ## Common mistakes

  **Using the hook as setup code**

  Do not make the component create package state, storage addresses, or low-level wiring. The component reads prepared app data.

  **Skipping loading and empty states**

  `data` can be `null`. Treat that as a real state, not an error.

  **Assuming every selector is global**

  A selector is scoped to the surface that Runtime Kit prepared. If a selector is not available, fix the package/surface boundary instead of hardcoding private reads in the component.

  **Deep importing unpublished Runtime Kit code**

  Only import from `@bitfield/runtime-kit/react`. If code needs private setup machinery, that code is not app component code.

  ## Quick reference

  ```tsx theme={null}
  const store = useBitfieldData<MyData>();
  const named = useBitfieldData<MyData>('input-name');
  const selected = useBitfieldData<MyData>({
    input: 'input-name',
    params: { id },
  });
  ```

  Return shape:

  ```ts theme={null}
  {
    data: T | null;
    loading: boolean;
    error: Error | null;
  }
  ```

  ## Now build the bigger version

  Build a real screen with two data names and one request.

  ```tsx theme={null}
  import { sendRequestToBitfieldTarget } from '@bitfield/runtime-kit';
  import { useBitfieldData } from '@bitfield/runtime-kit/react';

  type WelcomeCopy = { headline: string; body: string };
  type Checklist = { items: string[] };

  export function LaunchPanel() {
    const welcome = useBitfieldData<WelcomeCopy>('welcome-copy');
    const checklist = useBitfieldData<Checklist>('launch-checklist');

    async function getNextStep() {
      await sendRequestToBitfieldTarget({
        target: 'launch.next-step',
        payload: { completed: checklist.data?.items.length ?? 0 },
      });
    }

    if (welcome.loading || checklist.loading) return <section>Loading launch plan.</section>;
    if (welcome.error || checklist.error) return <section>Could not load launch plan.</section>;
    if (!welcome.data || !checklist.data) return <section>No launch plan yet.</section>;

    return (
      <section>
        <h2>{welcome.data.headline}</h2>
        <p>{welcome.data.body}</p>
        {checklist.data.items.map((item) => <p key={item}>{item}</p>)}
        <button type="button" onClick={getNextStep}>Get next step</button>
      </section>
    );
  }
  ```

  The component is doing real work, but it still only uses data names, an action name, and public payload shapes.
</div>
