API Reference
Complete API reference for @xndrjs/adapter-react.
useReactiveValue
Subscribe to a StatePort and return its current value. The component re-renders when the value changes.
Function Signature
function useReactiveValue<T>(reactiveValue: StatePort<T>): T;
Type Parameters:
T- The type of the value
Parameters:
reactiveValue: StatePort<T>- The StatePort to subscribe to (can beReactiveValue,ComputedValue, or anyStatePort)
Returns: The current value of type T
Behavior:
- Automatically detects
ComputedValueand uses shallow equality to prevent infinite loops - Uses React’s
useSyncExternalStorefor regularStatePort(efficient) - Uses internal state management for
ComputedValueto handle object equality correctly - Re-renders component when the value changes
Example:
import { useReactiveValue, useViewModel } from '@xndrjs/adapter-react';
import { ReactiveValue, createComputed, ViewModel } from '@xndrjs/core';
class CounterVM extends ViewModel {
count = new ReactiveValue(0);
doubled = createComputed(this.count)
.as((c) => c * 2)
.for(this);
}
function Counter() {
const vm = useViewModel(() => new CounterVM());
const countValue = useReactiveValue(vm.count); // number
const doubledValue = useReactiveValue(vm.doubled); // number
return (
<div>
<p>Count: {countValue}</p>
<p>Doubled: {doubledValue}</p>
</div>
);
}
useStatePort
Convert React useState to a StatePort. Returns a stable StatePort object that doesn’t change reference.
Function Signature
function useStatePort<T>(
value: T,
setValue: Dispatch<SetStateAction<T>>,
): StatePort<T>;
Type Parameters:
T- The type of the value
Parameters:
value: T- The current state value (fromuseState)setValue: Dispatch<SetStateAction<T>>- The state setter function (fromuseState)
Returns: A stable StatePort<T> object
Behavior:
- Returns a stable reference (doesn’t change on re-renders)
- The port remains reactive:
subscribe()notifies when value changes get()always returns the current value via internal ref- Can be used in
useRef/useMemodependencies without causing re-renders
Example:
import { useState } from 'react';
import { useStatePort, useViewModel } from '@xndrjs/adapter-react';
import { createComputed, ViewModel } from '@xndrjs/core';
class TodoAppVM extends ViewModel {
todoCount: ComputedValue<number>;
constructor(todosPort: StatePort<Todo[]>) {
super();
this.todoCount = createComputed(todosPort)
.as((todos) => todos.length)
.for(this);
}
}
function TodoApp() {
const [todos, setTodos] = useState<Todo[]>([]);
const todosPort = useStatePort(todos, setTodos);
const vm = useViewModel(() => new TodoAppVM(todosPort));
return <div>{/* ... */}</div>;
}
useCreateStatePort
Create a StatePort managed by React state. Returns a stable StatePort object.
Function Signature
function useCreateStatePort<T>(initialValue: T): StatePort<T>;
Type Parameters:
T- The type of the value
Parameters:
initialValue: T- The initial value
Returns: A stable StatePort<T> object
Behavior:
- Returns a stable reference (doesn’t change on re-renders)
- Uses React
useStateinternally - The port remains reactive:
subscribe()notifies when value changes - Can be used with computed values and other
StatePortoperations
Example:
import { useCreateStatePort, useReactiveValue, useViewModel } from '@xndrjs/adapter-react';
import { createComputed, ViewModel } from '@xndrjs/core';
class TodoAppVM extends ViewModel {
todoCount: ComputedValue<number>;
constructor(todosPort: StatePort<Todo[]>) {
super();
this.todoCount = createComputed(todosPort)
.as((todos) => todos.length)
.for(this);
}
}
function TodoApp() {
const todosPort = useCreateStatePort<Todo[]>([]);
const todos = useReactiveValue(todosPort);
const vm = useViewModel(() => new TodoAppVM(todosPort));
const addTodo = (todo: Todo) => {
todosPort.set((prev) => [...prev, todo]);
};
return (
<div>
<p>Total: {todos.length}</p>
{/* ... */}
</div>
);
}
Type Exports
All React adapter types are exported for TypeScript usage:
// All hooks are exported with their types
export { useReactiveValue, useStatePort, useCreateStatePort, useViewModel }; See Also
- Learn about Core concepts
- Explore FSM pattern
- Check out Getting Started