---
tags: zeta-dom-react
---
# Utilities
## `classNames`
Concatenates a list of CSS class names.
## `createBreakpointContext`
==Since `v0.2.3`==
Creates a state object and corresponding hook for multiple media queries.
```typescript
const { breakpoints, useBreakpoint } = createBreakpointContext({
isMobile: '(max-width: 700px)',
isTablet: '(max-width: 900px)'
});
function Component(props) {
const { isMobile, isTablet } = useBreakpoint();
/* ... */
}
// breakpoints is a state object that gives
// whether each media query matches now
// e.g. next line may give { isMobile: true, isTablet: false }
console.log(breakpoints);
```
## `domEventRef`
Allows binding listeners to Zeta DOM events.
```typescript!
function Component(props) {
const [state, setState] = useState(0);
return (
<div ref={domEventRef({ focusin })}></div>
);
function focusin() {
// callback has access to latest props or state
console.log(props.value, state);
}
}
```
## `innerTextOrHTML`
==Since `v0.3.1`==
Either inserts content using either `children`, or `dangerouslySetInnerHTML` if input is an object with `__html` property.
```typescript
function Component(props) {
return <div {...innerTextOrHTML(props.content)}></div>;
}
```
## `partial`
Partially updates a composite object state.
It can clean up code if the partial update does not depends on previous state.
```typescript
function Component(props) {
const [state, setState] = useState({ foo: 0, bar: 0 });
function onClick() {
partial(setState)({ foo: 1 });
// equivalent to:
// setState(s => ({ ...s, foo: 1 }));
}
}
```
It is also cleaner when passing event callback to child components:
```typescript
function Component(props) {
const [state, setState] = useState({ foo: 0, bar: 0 });
return <Other onChange={partial(setState, 'bar')}></Other>
// equivalent to:
// <Other onChange={bar => setState(s => ({ ...s, bar }))}></Other>
}
```
## `useAsync`
See [useAsync](/Rk3_Cez4RFyniUeMMN0eSA).
## `useDispose`
Creates a cleanup callback collector.
Callbacks pushed into the queue will be called when the component is unmounted.
```typescript
function Component(props) {
const dispose = useDispose();
useEffect(() => {
doSomeWork().then(() => {
dispose.push(() => console.log('Component unmounted'));
});
}, []]);
/* ... */
}
```
Callbacks can also be called manually by calling the `DisposeCallback`.
Executed callbacks are removed from the queue so that they will not be called twice.
```typescript
function Component(props) {
const dispose = useDispose();
useEffect(() => {
setTimeout(() => {
dispose(); // cleanup manually
}, 1000);
}, []);
/* ... */
}
```
## `useMediaQuery`
==Since `v0.2.3`==
Triggers component update when the matching state of the given media query has changed.
```typescript
function Component(props) {
const isMobile = useMediaQuery('(max-width: 700px)');
/* ... */
}
```
## `useMemoizedFunction`
Creates a memoized callback that invokes the supplied callback when called.
This reduces unnecessary `useEffect` cycles but at the same time the correct callback supplied in the last component cycle, which associates to the latest component state, can be called.
```typescript
function Component(props) {
const cb = useMemoizedFunction(() => {
console.log(props.value);
});
useEffect(() => {
// prints latest props.value every 1s
setInterval(cb, 1000);
}, [cb]);
}
```
## `useObservableProperty`
Listens and gets the value of a property of an object. The component is refreshed when the property has been updated.
```typescript
const obj = { value: 1 };
function Component() {
const value = useObservableProperty(obj, 'value');
return (<div>Value is {value}</div>);
}
// Component will print "Value is 2" when somewhere call update
function update() {
obj.value = 2;
}
```
## `useRefInitCallback`
Creates a React ref callback, that will invoke the supplied callback only once for each a new DOM element created.
It is generally used for one-time setup for DOM element, for example binding Zeta DOM events:
```typescript
function Component(props) {
const initRef = useRefInitCallback((element: HTMLElement) => {
// this callback will execute exactly once for the <DIV> element
zeta.dom.on(element, 'focusreturn', (e) => {
/* ... */
});
});
return (<div ref={initRef}></div>);
}
```
:::warning
**Important**: Since the callback is only called once for a DOM element in the component's lifetime, any variables referenced in the callback must be unchanged throughout the lifetime, such as created from [`React.useRef`](https://reactjs.org/docs/hooks-reference.html#useref). For functions, it can be wrapped by [`useMemoizedFunction`](#useMemoizedFunction).
:::
```typescript
function Component(props) {
const [counter, setCounter] = useState(0);
const [singletionObject] = useState({ count: 0 });
const counterRef = useRef(0);
const memoizedCallback = useMemoizedFunction(props.callback);
const inlineCallback = () => { /* ... */ };
const memoizedInlineCallback = useMemoizedFunction(inlineCallback);
const initRef = useRefInitCallback((element: HTMLElement) => {
// OK
singletionObject.count++;
counterRef.current++;
// OK, see `useMemoizedFunction`
memoizedCallback();
memoizedInlineCallback();
// not OK
counter; // -> state might change over the lifetime
props.callback(); // -> anything on props might be changed over the lifetime
// also callback may be bound to previous states
// which results in memory leaks
inlineCallback(); // -> definitely memory leaks
});
return (<div ref={initRef}></div>);
}
```
## `useUpdateTrigger`
==Since `v0.3.4`==
Creates a callback that trigger component update.
## `withSuspense`
==Since `v0.3.1`==
Creates a lazy component wrapped with `<Suspense>`.