Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

useResource

useResource is the primary way to fetch data with Atomic React. It returns a Resource object, that is still loading when initially returned. When the data is loaded, the component will re-render with the new data allowing you to show some UI before the content is available, resulting in a more responsive user experience.

The hook also subscribes to changes meaning that the component will update whenever the data changes clientside and even serverside. You essentially get real-time features for free!

import { useResource } from '@tomic/react'; export const Component = () => { const resource = useResource('https://my-atomic-server/my-resource'); // Show an error message if the resource has an error if (resource.error) { return <ErrorCard error={resource.error} /> } // Optionally show a loading state if (resource.loading) { return <Loader /> } return ( <p>{resource.title}</p> ) }

Typescript

Just like the store.getResource method, useResource can be annotated with a subject of a certain class.

import { useResource } from '@tomic/react'; import type { Author } from './ontologies/blogsite' // <-- Generated with @tomic/cli // ... const resource = useResource<Author>('https://my-atomic-server/moderndayshakespear69') const age = Date.now() - resource.props.yearOfBirth

Reference

Parameters

  • subject: string - The subject of the resource you want to fetch.
  • options: UseResourceOptions - (Optional) Options for how the store should fetch or update the resource.

UseResourceOptions:

NameTypeDescription
noWebSocketboolean(Optional) If true, uses HTTP to fetch resources instead of websockets
newResourceResource(Optional) If true, will not send a request to a server, it will simply create a new local resource.
trackstring[](Optional) By default useResource will update the reference of the resource whenever any property changes, both local and remote changes. Sometimes you want to only update the resource when certain properties change, you can use this option to specify which properties to track. Remote changes will still trigger a rerender.

Returns

Resource - The fetched resource (might still be in a loading state).

Views

A common way to build interfaces with Atomic React is to make a view component. Views are a concept where the component is responsible for rendering a resource in a certain way to fit in the context of the view type.

The view selects a component based on the resource’s class or renders a default view when there is no component for that class. In this example, we have a ResourceInline view that renders a resource inline in some text. For most resources, it will just render the name but for a Person or Product, it will render a special component.

// views/inline/ResourceInline.tsx import { useResource } from '@tomic/react'; import { shop } from '../../ontologies/shop'; // <-- Generated with @tomic/cli import { PersonInline } from './PersonInline'; import { ProductInline } from './ProductInline'; interface ResourceInlineProps { subject: string; } export interface ResourceInlineViewProps<T> { resource: Resource<T>; } export const ResourceInline = ({ subject }: ResourceInlineProps): JSX.Element => { const resource = useResource(subject); const Comp = resource.matchClass({ [shop.classes.product]: ProductInline, [shop.classes.person]: PersonInline, }, Default); return <Comp subject={subject} /> } const Default = ({ resource }: ResourceInlineViewProps<unknown>) => { return <span>{resource.title}</span> }

The PersonInline view will render a person resource inline. It could render a mention-like thing with the person’s name, their profile picture and a link to their profile for example.

// views/inline/PersonInline.tsx import { useResource, Resource, type Server } from '@tomic/react'; import type { Person } from '../../ontologies/social' // <-- Generated with @tomic/cli import type { ResourceInlineViewProps } from './ResourceInline'; export const PersonInline = ({ resource }: ResourceInlineViewProps<Person>) => { // Get the person's profile picture resource with the useResource hook const image = useResource<Server.File>(resource.props.image); return ( <span className="person-inline"> <img src={image.props.downloadUrl} className="profile-image-inline" /> <span>{resource.title}</span> </span> ) }