---
# System prepended metadata

title: Utilities
tags: [zeta-dom-react]

---

---
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>`.
