Component state

Views component state

Views comes with a built-in component state system. This system allows you to retrieve and update the state of any Views component from anywhere in your view.
We recommend users to use the Views component state for an easy-to-use and opinionated out-of-the-box experience. If you would rather manage state yourself, you can use Controlled component state.
Components that have state have a "State API" section in their documentation, for example Table state API.

Register component state

Use the auto-generated id returned by the useComponentState to register the component into the global component state.
In the following example, we pass the id from useComponentState into the TextInput. This registers the text input with the global state and allows us to access its state values, such as value.
tsx
Copied
1
const { id, value } = useComponentState();
2
return <TextInput id={id} defaultValue="Ha" />;
See each component's docs page for documentation on what state values it supports.
Instead of using the autogenerated id, you can also specify your own id in the call to useComponentState and pass the same id into the component.
tsx
Copied
1
const { id, value } = useComponentState("my-text-input");
2
return <TextInput id={id} defaultValue="Ha" />;

Access component state

Retrieve the component state from the return value of useComponentState.
The following example uses the value field on a TextInput's component state in the onClick prop of a Button. Try clicking on the Alert button. See that the input value from the component state is printed in the alert.
tsx
Copied
1
const { id, value } = useComponentState();
2
return (
3
<Stack direction="row">
4
<TextInput id={id} defaultValue="Ha" />
5
<Button onClick={() => alert(value)}>Alert</Button>
6
</Stack>
7
);

Mutate component state

You can also call functions that mutate the state.
The following example adds another Button that appends the string "ha" to the text input's value. Try clicking on the Append button.
tsx
Copied
1
const { id, value, setValue } = useComponentState();
2
return (
3
<Stack direction="row">
4
<TextInput id={id} defaultValue="Ha" />
5
<Button onClick={() => alert(value)}>Alert</Button>
6
<Button
7
onClick={() => {
8
setValue(`${value}ha`);
9
}}
10
>
11
Append
12
</Button>
13
</Stack>
14
);

React to changes in component state

If you want to be notified when a component's state changes, you can use React's useEffect hook to call a function when the state changes.
tsx
Copied
1
const { id, value } = useComponentState();
2
useEffect(() => {
3
// Call this function every time the value changes.
4
showNotification({ message: `Value changed to ${value}` });
5
}, [value]);
6
return (
7
<Stack direction="row">
8
<TextInput id={id} />
9
<Button onClick={() => alert(value)}>Alert</Button>
10
</Stack>
11
);

Debug component state

In Studio, you can view a list of components that are integrated with Views component state and the state information for each component in the Components tab of the debug panel. The state information will update as you develop and interact with your view.

Controlled component state

If you would rather manage state yourself, you can use your state system of choice and treat the Views components as controlled components.
In the following snippet, we rewrite the above example using React's useState hook. We can manually manage the state of the TextInput component using its value and onChange props.
tsx
Copied
1
const [value, setValue] = useState("Ha");
2
return (
3
<Stack direction="row">
4
<TextInput
5
value={value}
6
onChange={(e) => {
7
setValue(e.target.value);
8
}}
9
/>
10
<Button onClick={() => alert(value)}>Alert</Button>
11
<Button
12
onClick={() => {
13
setValue(`${value}ha`);
14
}}
15
>
16
Append
17
</Button>
18
</Stack>
19
);

TypeScript for type safety

We recommend using Generics to keep the component state type-safe.
In the following example, we tell useComponentState that the component it is registered with is a table. This automatically types state fields such as selectedRow while erroring out on fields that don't exist on the table state such as value.
tsx
Copied
1
const { id, selectedRow } = useComponentState<TableState>();
2
// The following line would error since `value` does not exist on `TableState`.
3
// const { id, value } = useComponentState<TableState>();
4
return (
5
<Stack>
6
<Table id={id} columns={columns} data={data} rowSelection="single" />
7
{selectedRow && <Text>{`Selected ${selectedRow.name}`}</Text>}
8
</Stack>
9
);
Most of our examples do not use types for brevity, but we strongly recommend using types throughout your view!