Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import React, { FormEvent, useEffect, useState } from 'react';
- import { atom, selector, useRecoilCallback, useRecoilValue } from 'recoil';
- /**
- * Description: ASYNC DEMO and useRecoilCallback
- * This demo shows how to do GET, DELETE and POST
- * BONUS: Another use of selectors
- * TODO: fix getUsers dependency in useEffect
- * ASK: best way to handle CRUD operations?
- */
- type User = { id: number, name: string, subscribe: boolean };
- const MAX_USERS = 12;
- const currentUsersState = atom<User[]>({
- key: 'users',
- default: []
- })
- const remainingUsers = selector<number>({
- key: 'remainingUsers',
- get: ({ get }) => {
- return MAX_USERS - get(currentUsersState).length
- },
- })
- ///// ROOT COMPO /////
- export const Demo6: React.FC = () => {
- const users = useRecoilValue(currentUsersState)
- const getUsers = useRecoilCallback(({set}) => async () => {
- const response = await fetch('https://jsonplaceholder.typicode.com/users/')
- set(currentUsersState, await response.json());
- }, []);
- useEffect(() => {
- getUsers();
- }, [getUsers])
- const addUser = useRecoilCallback(({set}) => async user => {
- const response = await fetch('https://jsonplaceholder.typicode.com/users',
- {
- method: 'POST', body: JSON.stringify(user),
- headers: { 'Content-Type': 'application/json' },
- })
- set(currentUsersState, [...users, await response.json()]);
- });
- const deleteUser = useRecoilCallback(({set}) => async id => {
- const response = await fetch('https://jsonplaceholder.typicode.com/users/1', { method: 'DELETE'})
- set(currentUsersState, users.filter((u: User) => u.id !== id));
- });
- return (
- <React.Suspense fallback={<div>Loading...</div>}>
- <h1>Demo6</h1>
- <UserForm addUser={addUser}/>
- <UsersListCounter />
- <UsersList users={users} deleteUser={deleteUser} />
- </React.Suspense >
- )
- };
- ////// CHILD COMPONENTS: FORM /////
- interface UserFormProps {
- addUser: (payload: Partial<User>) => void;
- }
- function UserForm(props: UserFormProps) {
- const [value, setValue] = useState<string>('')
- const remainUsers = useRecoilValue(remainingUsers)
- function submit(e: FormEvent) {
- e.preventDefault();
- if (remainUsers > 0) {
- props.addUser({ name: value, subscribe: true })
- setValue('')
- }
- }
- return (
- <form onSubmit={submit}>
- <input type="text" value={value} onChange={e => setValue(e.target.value)} placeholder="Write something and press ENTER" />
- </form>
- )
- }
- ////// CHILD COMPONENTS: LIST /////
- interface UserListProps {
- users: User[];
- deleteUser: (id: number) => void;
- }
- function UsersList(props: UserListProps) {
- return <div>
- {
- props.users?.map((u: User, index: number) => {
- return <li key={index} onClick={() => props.deleteUser(u.id)}>{u.name}</li>
- })
- }
- </div>
- }
- ////// CHILD COMPONENTS: LIST COUNTER /////
- function UsersListCounter() {
- const users = useRecoilValue(currentUsersState)
- const remainUsers = useRecoilValue(remainingUsers)
- return <div>
- Still { remainUsers} of {users.length}
- </div>
- }
Add Comment
Please, Sign In to add comment