# Component State in Adaptable Options

Canonical page: https://www.adaptabletools.com/docs/react-dev-guide-tutorial-component-state-in-adaptable-options

- How to pass **component state** into [Adaptable Options](https://www.adaptabletools.com/docs/technical-reference-adaptable-options/index.md) when using AdapTable React
- Applies when options must react to React state (e.g. custom menu items that read or update app state)

The [Adaptable Options](https://www.adaptabletools.com/docs/technical-reference-adaptable-options/index.md) object, once passed to the Adaptable instance at creation, **is evaluated only once**.

- This means that any changes made to [Adaptable Options](https://www.adaptabletools.com/docs/technical-reference-adaptable-options/index.md) after this point will **not** be recognized
- Nor will they be reflected in the AdapTable instance

If you need to have dynamic options that can change based on the component state, you should **not** directly change the `AdaptableOptions` object.

Instead, you should define functions within the `AdaptableOptions` object that **reference the latest values of the component state**.

These functions will be evaluated at runtime, ensuring that the most recent state values are used.

This pattern is for configuration held in [Adaptable Options](https://www.adaptabletools.com/docs/technical-reference-adaptable-options/index.md). When you render bespoke UI with `ReactFrameworkComponent` (custom toolbars, tool panels, and so on), you can often share state via React context instead — see [Using State](https://www.adaptabletools.com/docs/ui-tutorial-building-custom-components/index.md#using-state) in [Building Custom Components](https://www.adaptabletools.com/docs/ui-tutorial-building-custom-components/index.md).

**Example: Passing Component State in AdaptableOptions**

Passing Component State in AdaptableOptions (React)

- This example shows how to correctly pass component state in the `AdaptableOptions` parameter
- We create a reference (`useRef()`) to the up-to-date custom menu item and use it in the `AdaptableOptions` object
- The custom menu item:
  - displays the current value of the `componentState`
  - updates the `componentState` when clicked

Demo project (React); the files without a marker are shown below:

```text
src/
  agGridModules.ts     [template]
  App.tsx
  columnDefs.ts        [template]
  gridOptions.ts       [template]
  index.tsx            [template]
  onAdaptableReady.ts  [template]
  rowData.ts           [template]
  styles.css           [template]
package.json           [template]
tsconfig.json          [template]
```

Files marked `[template]` are the same in every demo; see the [demo template](https://www.adaptabletools.com/llms/demo-template.md#react).

**`src/App.tsx`**

```ts
import * as React from 'react';
import {MutableRefObject, useMemo, useState} from 'react';
import {
  Adaptable,
  AdaptableOptions,
  AdaptableReadyInfo,
  UserContextMenuItem,
  CustomContextMenuContext,
  AdaptableApi,
} from '@adaptabletools/adaptable-react-aggrid';

// import adaptable css
import '@adaptabletools/adaptable-react-aggrid/index.css';
// import aggrid themes (using Balham theme)

import './styles.css';
import {agGridModules} from './agGridModules';
import {GridOptions} from 'ag-grid-enterprise';
import {onAdaptableReady} from './onAdaptableReady';
import {WebFramework} from './rowData';
import {gridOptions} from './gridOptions';

const App: React.FunctionComponent = () => {
  const adaptableApiRef = React.useRef<AdaptableApi>(null);

  const [componentState, setComponentState] = useState<number>(0);

  // keep a reference to the up-to-date context menu item
  // this reference will be passed in the custom context menu function
  const updateCmpStateMenuItem = React.useRef<UserContextMenuItem>(null);
  updateCmpStateMenuItem.current = {
    menuType: 'User',
    label: `Current counter: ${componentState}`,
    subMenuItems: [
      {
        menuType: 'User',
        label: 'Increment',
        icon: {
          name: 'plus',
        },
        onClick: () => {
          setComponentState(componentState + 1);
        },
      },
      {
        menuType: 'User',
        label: 'Decrement',
        icon: {
          name: 'minus',
        },
        onClick: () => {
          setComponentState(componentState - 1);
        },
      },
    ],
  };

  // adaptableOptions prop is only evaluated once, at initialisation
  // even if you create a new AdaptableOptions object, Adaptable won't use the latest reference
  // so instead, we need to reference the latest values inside the functions defined in the AdaptableOptions object
  const adaptableOptions: AdaptableOptions<WebFramework> = useMemo(
    () => ({
      primaryKey: 'id',
      adaptableId: 'React Component State',
      contextMenuOptions: {
        customContextMenu: (context: CustomContextMenuContext) => {
          const {defaultAdaptableMenuStructure} = context;

          return [
            // !!! we use the reference to the up-to-date context menu item
            updateCmpStateMenuItem.current!,
            '-',
            ...defaultAdaptableMenuStructure,
          ];
        },
      },
      initialState: {
        Layout: {
          CurrentLayout: 'Special Column View',
          Layouts: [
            {
              Name: 'Special Column View',
              TableColumns: [
                'name',
                'language',
                'github_stars',
                'github_watchers',
                'subscribersRatio',
                'comments',
                'open_pr_count',
                'closed_issues_count',
                'created_at',
                'updated_at',
                'pushed_at',
                'license',
                'created_at',
                'has_wiki',
              ],
              AutoSizeColumns: true,
            },
          ],
        },
      },
    }),
    []
  );

  const agGridOptions: GridOptions<WebFramework> = useMemo(
    () => gridOptions,
    []
  );

  return (
    <div style={{display: 'flex', flexFlow: 'column', height: '100vh'}}>
      <Adaptable.Provider
        gridOptions={agGridOptions}
        adaptableOptions={adaptableOptions}
        modules={[...agGridModules]}
        onAdaptableReady={(adaptableReadyInfo: AdaptableReadyInfo) => {
          // save a reference to adaptable api
          adaptableApiRef.current = adaptableReadyInfo.adaptableApi;
          onAdaptableReady(adaptableReadyInfo);
        }}>
        <Adaptable.UI style={{flex: 'none'}} />
        <Adaptable.AgGridReact />
      </Adaptable.Provider>
    </div>
  );
};
export default App;
```


