Skip to content

React integration

To integrate Alette Signal with React UI framework, install the React adapter:

sh
pnpm add @alette/signal-react@latest
sh
npm install @alette/signal-react@latest
sh
yarn add @alette/signal-react@latest

Usage with components

To use request blueprints with React components, pass them to the useApi() hook:

tsx
import { useApi } from '@alette/signal-react';
import { getPosts } from '../api/posts' 

const Component = () => {
    const {
        isUninitialized,
        isLoading,
        isSuccess,
        isError,
        data,
        error,
		settings,
        execute,
        cancel,
    } = useApi(getPosts);
    
    return <div>{/* ... */}</div>
}

DANGER

  1. The useApi() hook mounts the request and initialized its middleware once. If the React component re-renders, the middleware passed to the .with() request blueprint method will not be reinitialized:
tsx
useApi(
    getPosts.with(
    	// runOnMount() will be initialized once
        runOnMount(false)
	)
)
  1. useApi() initializing middleware once makes passing component properties directly to the middleware result in stale data:
tsx
const Component = ({ name }) => {
    const {/* ... */} = useApi(
        getPosts.with(
            // The "name" property will not be updated
			// after the component re-renders.
            body({ name })
		)
	);
}

TIP

The useApi() hook accepts query, mutation and custom request blueprints, as well as other request blueprints created by plugin authors.

Reloading on changes

To reload a request on React component property changes, bind properties to the request and pass them to the useApi() dependency array:

tsx
const Component = ({ name }) => {
    const {/* ... */} = useApi(
        getPosts.using(() => ({
			args: name
		}))
		// When the "name" property changes,
		// the request will be reloaded automatically
		// with the updated "name" value.
		[name]
	);
}

TIP

The useApi() dependency array can accept multiple properties to track:

tsx
const Component = ({ name, value, id }) => {
    const {/* ... */} = useApi(
        getPosts.using(() => ({
            args: {
                id,
                name,
				value,
			}
        }))
		[name, value, id]
    );
}

WARNING

Passing an empty dependency array to the useApi() hook results in the request reloading once on mount, and skipping next reloads during component re-renders:

tsx
const Component = ({ name, value, id }) => {
    const {/* ... */} = useApi(
        getPosts.using(() => ({
            args: {
                id,
                name,
				value,
			}
        })),
		// The request will be reloaded once on 
		// mount if the runOnMount() middleware was provided.
		[]
    );
}

WARNING

Omitting the dependency array from the useApi() hook results in the request reloading once on mount, and skipping next reloads during component re-renders:

tsx
const Component = ({ name, value, id }) => {
    const {/* ... */} = useApi(
        // The request will be reloaded once on 
        // mount if the runOnMount() middleware was provided.
        getPosts.using(() => ({
            args: {
                id,
                name,
				value,
			}
        })),
    );
}

Used request settings

To get used requests settings, use the exposed settings property:

tsx
const Component = ({ name }) => {
    const { settings } = useApi(
        getPosts.using(() => ({
			args: name
		}))
		[name]
	);
    
	return (
        <p>
            Last used name is {settings?.args.name || name}
		</p>
	)
}

Did you know?

Alette Signal React integration implementation is 35 lines total, excluding comments.

Released under the Apache 2.0 License.