[Recoil] Optimising API Calls
Using cache class to reduce API calls
import {Button} from '@chakra-ui/button'
import {Input} from '@chakra-ui/input'
import {Box, Divider, Heading, VStack} from '@chakra-ui/layout'
import React, {useState} from 'react'
import {
atom,
atomFamily,
DefaultValue,
useRecoilCallback,
useRecoilState,
useRecoilValue,
useResetRecoilState,
} from 'recoil'
import {shoppingListAPI} from './shippingAPI'
type ItemType = {
label: string
checked: boolean
}
class CachedAPI {
cacheItenms: Record<string, ItemType> | undefined
private async getItems() {
if (this.cacheItenms) return this.cacheItenms
this.cacheItenms = await shoppingListAPI.getItems()
return this.cacheItenms
}
async getIds() {
const items = await this.getItems()
return Object.keys(items).map((id) => parseInt(id))
}
async getItem(id: number) {
const items = await this.getItems()
return items[id]
}
}
const cachedAPI = new CachedAPI()
const idsState = atom<number[]>({
key: 'ids',
default: [],
effects_UNSTABLE: [
({setSelf}) => {
setSelf(cachedAPI.getIds())
},
],
})
const itemState = atomFamily<ItemType, number>({
key: 'item',
default: {label: '', checked: false},
effects_UNSTABLE: (id) => [
({onSet, setSelf, trigger}) => {
setSelf(cachedAPI.getItem(id))
onSet((item, oldItem) => {
if (oldItem instanceof DefaultValue && trigger === 'get') return
if (item instanceof DefaultValue) {
shoppingListAPI.deleteItem(id)
} else {
shoppingListAPI.createOrUpdateItem(id, item)
}
})
},
],
})
export const AsyncEffects2 = () => {
const ids = useRecoilValue(idsState)
const resetList = useResetRecoilState(idsState)
const nextId = ids.length
const insertItem = useRecoilCallback(({set}) => (label: string) => {
set(idsState, [...ids, nextId])
set(itemState(nextId), {label, checked: false})
})
return (
<Container onClear={() => resetList()}>
{ids.map((id) => (
<Item key={id} id={id} />
))}
<NewItemInput
onInsert={(label) => {
insertItem(label)
}}
/>
</Container>
)
}
const Container: React.FC<{onClear: () => void}> = ({children, onClear}) => {
return (
<Box display="flex" flexDir="column" alignItems="center" pt={10}>
<Box width="400px" backgroundColor="yellow.100" p={5} borderRadius="lg">
<Heading size="lg" mb={4}>
Shopping List
</Heading>
<VStack spacing={3} divider={<Divider borderColor="rgba(86, 0, 0, 0.48)" />}>
{children}
</VStack>
</Box>
<Button variant="link" mt={3} onClick={onClear}>
Clear list
</Button>
</Box>
)
}
type ItemProps = {
id: number
}
const Item = ({id}: ItemProps) => {
const [item, setItem] = useRecoilState(itemState(id))
return (
<Box
rounded="md"
textDecoration={item.checked ? 'line-through' : ''}
opacity={item.checked ? 0.5 : 1}
_hover={{textDecoration: 'line-through'}}
cursor="pointer"
width="100%"
onClick={() => setItem({...item, checked: !item.checked})}
>
{item.label}
</Box>
)
}
const NewItemInput = ({onInsert}: {onInsert: (label: string) => void}) => {
const [value, setValue] = useState('')
return (
<Input
value={value}
placeholder="New item"
padding={0}
height="auto"
border="none"
_focus={{border: 'none'}}
_placeholder={{color: 'rgba(86, 0, 0, 0.48)'}}
onChange={(e) => {
setValue(e.currentTarget.value)
}}
onKeyPress={({key}) => {
if (key === 'Enter') {
onInsert(value)
setValue('')
}
}}
/>
)
}
分类:
React
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
2021-10-12 [SAP] 36. Storage getway
2020-10-12 [Kotlin] Enum class
2020-10-12 [Kotlin] Singleton Object
2020-10-12 [Kotlin] Data class
2020-10-12 [Kotlin] Class / Abstract class / Example
2020-10-12 [Kotlin] Overriding Rules (super, final)
2020-10-12 [Kotlin] interface