We recently release two new package versions Rest [email protected] and @rest-hooks/[email protected]. These include some solutions to long-standing user-requested functionality. Additionally, we'll give a preview of even more features soon to come.
Rest Hooks 6.5
- Better partial hydration SSR support and compatibility with NextJS SSR
- Controller.getState() provides access to state inside event handlers
@rest-hooks/rest 6.1
- Query provides programmatic access to the Rest Hooks store.
- schema.All() retrieves all entities in the store. Very useful with Query
New Features
Partial Hydration SSR
Client-side React concurrent features like startTransition only work with Context. However, server-side, React will only re-render Suspended elements. This means any context provides must suspend the context themselves, which would mean the suspense boundaries would have to be around the entire application.
With this update, we use useSyncExternalStore if when running SSR. This is not ideal to replace client render because it eliminates startTransition benefits client-side.
In addition, the SSR helpers were updated to better handle these use cases. You can use the @rest-hooks/ssr readme for instructions on usage with vanilla React 18.
What's next
Currently there is no documentation on SSR on this docs site, even though we have one working demo and @rest-hooks/ssr readme for vanilla React 18. We will soon be adding guides to this site for React 18, as well as frameworks like NextJS.
Controller.getState()
Oftentimes control flow in an event handler after a mutation relies on the data from that mutation. For instance, performing a url redirect to a newly created member. When taking advantage of the Rest Hooks data model for things like computed properties this can mean having the raw fetch response is not enough.
With Controller.getState() you can access the same (with referential equality guarantees!) data you would get from a data-binding hook like useSuspense or useCache.
Be careful though as this can lead to race conditions if used outside of an event handler. For this reason we kept its usage explicit so you can always see where the data is coming from.
const controller = useController();
const updateHandler = useCallback(
async updatePayload => {
await controller.fetch(
MyResource.update,
{ id },
updatePayload,
);
const denormalized = controller.getResponse(
MyResource.update,
{ id },
updatePayload,
controller.getState(),
);
redirect(denormalized.getterUrl);
},
[id],
);
Query
Query provides programmatic access to the Rest Hooks store. This improves post-processing use cases, by providing a mechanism to take advtange of the global memoization for improved performance as well as easy code-sharing of Endpoint interfaces.
[{"id":"123","name":"Jim"},{"id":"456","name":"Jane"},{"id":"777","name":"Albatras","isAdmin":true}]
import { Query, schema } from '@rest-hooks/rest';import { UserResource, User } from './api/User';const sortedUsers = new Query(new schema.All(User),(entries, { asc } = { asc: false }) => {const sorted = [...entries].sort((a, b) => a.name.localeCompare(b.name));if (asc) return sorted;return sorted.reverse();});function UsersPage() {useFetch(UserResource.getList);const users = useCache(sortedUsers, { asc: true });if (!users) return <div>No users in cache yet</div>;return (<div>{users.map(user => (<div key={user.pk()}>{user.name}</div>))}</div>);}render(<UsersPage />);
schema.All
schema.All retrieves all entities in cache as an Array. This provides a new way of accessing the Rest Hooks store, and when combined with Query can be very powerful.
What's next
Inspired by BackboneJS, Collections
are a new schema
planned to better handle many-to-one and many-to-many relationships alongside creates.
They should eliminate the need for programmatic updates
controller.fetch(
MyResource.getList.create,
// same params as getList
{ owner, repo },
// payload ('body')
FormObject
);