Skip to main content

One post tagged with "collections"

View All Tags

· 6 min read
Nathaniel Tucker

Collections enable Arrays and Objects to be easily extended by pushing or unshifting new members. The namesake comes from Backbone Collections.

Collections were first introduced in @rest-hooks/[email protected]. @rest-hooks/rest@7 takes this one step further, but using them in Resource.getList.

Fixtures
GET /users
async response(...args){return(await UserResource.getList(...args)).slice(0,3);}
GET /todos
async response(...args){return(await TodoResource.getList(...args)).slice(0,7);}
PATCH /todos/:id
async response(...args){return{...(await TodoResource.partialUpdate(...args)),id:args?.[0]?.id};}
POST /todos
async response(...args){//await new Promise(resolve => setTimeout(resolve, 500));
return{...(await TodoResource.getList.push(...args)),id:randomId()};}
TodoResource
import { Entity } from '@rest-hooks/rest';
import { createResource } from '@rest-hooks/rest/next';
export class Todo extends Entity {
id = 0;
userId = 0;
title = '';
completed = false;
pk() {
return `${this.id}`;
}
static key = 'Todo';
}
export const TodoResource = createResource({
urlPrefix: 'https://jsonplaceholder.typicode.com',
path: '/todos/:id',
searchParams: {} as { userId?: string | number } | undefined,
schema: Todo,
optimistic: true,
});
TodoItem
import { useController } from '@rest-hooks/react/next';
import { TodoResource, type Todo } from './TodoResource';
export default function TodoItem({ todo }: { todo: Todo }) {
const ctrl = useController();
const handleChange = e =>
ctrl.fetch(
TodoResource.partialUpdate,
{ id: todo.id },
{ completed: e.currentTarget.checked },
);
const handleDelete = () =>
ctrl.fetch(TodoResource.delete, {
id: todo.id,
});
return (
<div className="listItem nogap">
<label>
<input
type="checkbox"
checked={todo.completed}
onChange={handleChange}
/>
{todo.completed ? <strike>{todo.title}</strike> : todo.title}
</label>
<CancelButton onClick={handleDelete} />
</div>
);
}
CreateTodo
import { useController } from '@rest-hooks/react/next';
import { TodoResource } from './TodoResource';
export default function CreateTodo({ userId }: { userId: number }) {
const ctrl = useController();
const handleKeyDown = async e => {
if (e.key === 'Enter') {
ctrl.fetch(TodoResource.getList.push, {
userId,
title: e.currentTarget.value,
id: Math.random(),
});
e.currentTarget.value = '';
}
};
return (
<div className="listItem nogap">
<label>
<input type="checkbox" name="new" checked={false} disabled />
<input type="text" onKeyDown={handleKeyDown} />
</label>
</div>
);
}
TodoList
import { useSuspense } from '@rest-hooks/react/next';
import { TodoResource } from './TodoResource';
import TodoItem from './TodoItem';
import CreateTodo from './CreateTodo';
function TodoList() {
const userId = 1;
const todos = useSuspense(TodoResource.getList, { userId });
return (
<div>
{todos.map(todo => (
<TodoItem key={todo.pk()} todo={todo} />
))}
<CreateTodo userId={userId} />
</div>
);
}
render(<TodoList />);
Live Preview
Loading...
Store

Upgrading is quite simple, as @rest-hooks/rest/next and @rest-hooks/react/next were introduced to allow incremental adoption of the new APIs changed in this release. This makes the actual upgrade a simple import rename.

Other highlights include

Upgrade to Rest Hooks 8 guide