LLM-CodeSlim:法學碩士(LLM)
2024 年 9 月 14 日ЧГК-GPT,還有 насколько хорош новый ChatGpt o1-preview в спортивном «Что?de?
2024 年 9 月 14 日Библиотека RRC для управления запросами и кэшем на базе Redux: [лучшая] алтпенаизе Redux: [лучшая] алтенаии
WordPress
React-redux-cache (RRC) 的核心功能 – React 中的快取和緩存 反應查詢 и RTK查詢, при этом имеет похожий, но очень простой интерфейс。
RRC можно рассматривать как ApolloClient для протоколов, отличных от GraphQL (хотя енсе 3uxых от GraphQL (хот лекторы) , экшены (動作) и редц кэшированным состоя埃姆。
WordPress Зачем?
Далее пойдет сравнение с имеющимися библиотеками для управления запр оит поль зоваться библиотеками для этого, 和 не нисатѕпсе вр п – оставимтутемуемуемуем
-
Полный контроль над хранилищем не только дает больше возможностеао, иольше возможностеао, иольше возможностеао, иль меньше костылей 你好,世界,你好,我是你的朋友。
-
Redux это отличный – простой и проверенный инструмент для хранения медл / каждое жатие клавиши оользовататие клавиши оользователе。 普羅格·沃達 для тех,кто знаком с библиотекой – минимальный。 Экосистема предлагает。 удобную отладку 和 множетсво готовых решенийтаких как хранение состояния на диске (redux-persist)。
-
Нормализация – это лучший способ поддерживать согласованное сос и сокращает количество запросов 和 без проблем позволяет сразу отображать кэшированные данные три навпоианные данные три навпоианные данные три навпоианные данные три навпоианные данн улучшает пользовательский опытАналогов、подерживающих нормализацию、практически нет – ApolloClient 為 GraphQL 提供服務,並為您提供協助。
-
Легковесность, как размера библиотеки, так и е интерфейса – еще одно преимуще тм
Краткое сравнение библиотек в таблице:
反應查詢 |
阿波羅客戶端 |
RTK查詢 |
RRC |
|
Полный доступ хранилищу |
– |
– |
Отсутствуют экшены для изменения состояния вручную. “數據縮寫=“+-”>+- |
+ |
休息時間 |
+ |
– |
+ |
+ |
Нормализация |
– |
+ |
– |
+ |
Бесконечная пагинация |
+ |
+ |
Да, вот такой “穆斯科” этот RTK 查詢。 “資料縮寫=“-”>- |
+ |
Не переусложнена — моя субъективная оценка, где учитываетсяткривая к реализация бесконечнойц диниация бесконе но угие аспекты。 ” data-abbr=”Не переусложнена”>Не переусложнена |
+ |
– |
– |
+ |
普魯亞諾斯提 |
+ |
+ |
RTK 與 RTK 查詢、RTK 查詢、RTK 查詢ательной частью、пользуется ещё меньшейьопулярнссё меньшейьопулярнстё меньшейьопулярнстё меньшейьопулярнстё меншей “資料縮寫=“-*”>- |
– |
反應?
Поддержка всевозможных UI библиотек кроме самой популярной (используеои опулярной (используеоиопулое
WordPress 範例
Для запуска примеров из папки /example
используйте npm run example
. Доступны три примера:
-
С нормализацией (рекомендуется)。
-
Без нормализации。
-
Без нормализации, оптимизированный。
Данные примеры – лучшее доказательство того, как сильно зависит пол ния。
-
пользователь вынужден наблюдать спинеры и прочие состояния загруоки,чие состояния загруоки,чие состояния загр не закончится。
-
запросы постоянно отправляются, даже если данные все еще достаточно свежисе еще достаточносве
Redux 的例子
{ entities: { // Каждый тип имеет свой словарь сущностей, хранящихся по id. users: { "0": {id: 0, bankId: "0", name: "User 0 *"}, "1": {id: 1, bankId: "1", name: "User 1 *"}, "2": {id: 2, bankId: "2", name: "User 2"}, "3": {id: 3, bankId: "3", name: "User 3"} }, banks: { "0": {id: "0", name: "Bank 0"}, "1": {id: "1", name: "Bank 1"}, "2": {id: "2", name: "Bank 2"}, "3": {id: "3", name: "Bank 3"} } }, queries: { // Каждый запрос имеет свой словарь состояний, хранящихся по ключу кэша, генерируемого из параметров запроса getUser: { "2": {loading: false, error: undefined, result: 2, params: 2}, "3": {loading: true, params: 3} }, getUsers: { // Пример состояния с пагинацией под переопределенным ключом кэша (см. далее в пункте про пагинацию) "all-pages": { loading: false, result: {items: [0,1,2], page: 1}, params: {page: 1} } } }, mutations: { // Каждая мутация так же имеет свое состояния updateUser: { loading: false, result: 1, params: {id: 1, name: "User 1 *"} } }}
範例 redux без нормализации
{ // Словарь сущностей используется только для нормализации, и здесь пуст entities: {}, queries: { // Каждый запрос имеет свой словарь состояний, хранящихся по ключу кэша, генерируемого из параметров запроса getUser: { "2": { loading: false, error: undefined, result: {id: 2, bank: {id: "2", name: "Bank 2"}, name: "User 2"}, params: 2 }, "3": {loading: true, params: 3} }, getUsers: { // Пример состояния с пагинацией под переопределенным ключом кэша (см. далее в пункте про пагинацию) "all-pages": { loading: false, result: { items: [ {id: 0, bank: {id: "0", name: "Bank 0"}, name: "User 0 *"}, {id: 1, bank: {id: "1", name: "Bank 1"}, name: "User 1 *"}, {id: 2, bank: {id: "2", name: "Bank 2"}, name: "User 2"} ], page: 1 }, params: {page: 1} } } }, mutations: { // Каждая мутация так же имеет свое состояния updateUser: { loading: false, result: {id: 1, bank: {id: "1", name: "Bank 1"}, name: "User 1 *"}, params: {id: 1, name: "User 1 *"} } }}
赫斯塔諾夫卡
react
, redux
и react-redux
являютсяpeer-зависимостями。
npm add react-redux-cache react redux react-redux
Инициализация
Единственная функция, которую нужно импортировать — это createCache
которая создаёт полностью типизированные редьюсер, хукитэкшены,селвввои юсер, хукитэкшены,селвввоои юсер, ко кэшей、с колько нужно、но учтите、что норс Все типы、запросы 和 мутации типы、запросы 和 мутации типы、запро ы 和 мутации типы、запр
快取.ts
export const { cache, reducer, hooks: {useClient, useMutation, useQuery},}=createCache({ // Используется как префикс для экшенов и в селекторе выбора состояния кэша из состояния redux name: 'cache', // Словарь соответствия нормализованных сущностей их типам TS // Можно оставить пустым, если нормализация не нужна typenames: { users: {} as User, // здесь сущности `users` будут иметь тип `User` banks: {} as Bank, }, queries: { getUsers: { query: getUsers }, getUser: { query: getUser }, }, mutations: { updateUser: { mutation: updateUser }, removeUser: { mutation: removeUser }, },})
Для нормализации требуется две вещи:
-
Задать 類型名稱 при создании кэша – список всех сущностей 和 соответствующие им типы TS。
-
Возвращать из функций 查詢與突變 объект, содержащий помимо поля 結果 данн
type EntityChanges={ // Сущности, что будут объединены с имеющимися в кэше merge?: PartialEntitiesMap // Сущности что заменят имеющиеся в кэше replace?: Partial> // Идентификаторы сущностей, что будут удалены из кэша remove?: EntityIds // Алиас для `merge` для поддержки библиотеки normalizr entities?: EntityChanges['merge']}
商店.ts
Создайте 商店 как обычно、передав новый редьюсер кэша под именем кэшао кэша под именем кэшао ЕЎ олнител ьно передать селетоис
const store=configureStore({ reducer: { [cache.name]: reducer, ... }})
api.ts
Результат запроса должен быть типа QueryResponse
результат мутации — типа MutationResponse
Для нормализации в этом примере используется пакет normalizr, но можнор ипу。 ле – бэкэнд возвращает уже нормализованные данные。
// Пример запроса с нормализацией (рекомендуется)export const getUser=async (id: number)=> { const result=await ... const normalizedResult: { // result - id пользователя result: number // entities содержат все нормализованные сущности entities: { users: Record banks: Record } }=normalize(result, getUserSchema) return normalizedResult}// Пример запроса без нормализацииexport const getBank=(id: string)=> { const result: Bank=... return {result}}// Пример мутации с нормализациейexport const removeUser=async (id: number)=> { await ... return { remove: { users: [id] }, // result не задат, но указан id пользователя, что должен быть удален из кэша }}
用戶螢幕.tsx
export const UserScreen=()=> { const {id}=useParams() // useQuery подключается к состоянию redux, и если пользователь с таким id уже закэширован, // запрос не будет выполнен (по умолчанию политика кэширования 'cache-first') const [{result: userId, loading, error}]=useQuery({ query: 'getUser', params: Number(id), }) const [updateUser, {loading: updatingUser}]=useMutation({ mutation: 'updateUser', }) // Этот hook возвращает сущности с правильными типами — User и Bank const user=useSelectEntityById(userId, 'users') const bank=useSelectEntityById(user?.bankId, 'banks') if (loading) { return ... } return ...}
WordPress Продвинутые возможности
Расширенная политика кэширования
По умолчанию политика cache-first
上一頁 下一頁尾頁 ответе другого запроса или нормализованном кэше. 跳過:
export const UserScreen=()=> { ... const user=useSelectEntityById(userId, 'users') const [{loading, error}]=useQuery({ query: 'getUser', params: userId, skip: !!user // Пропускаем запрос, если пользователь уже закэширован ранее, например, запросом getUsers }) ...}
Мы можем дополнительно проверить、достаточно ли полный объект、или、напроер
skip: !!user && isFullUser(user)
Другой подход — установить 跳過:true 和 вручную запускать запрос,когдаооооокат
export const UserScreen=()=> { const screenIsVisible=useScreenIsVisible() const [{result, loading, error}, fetchUser]=useQuery({ query: 'getUser', params: userId, skip: true }) useEffect(()=> { if (screenIsVisible) { fetchUser() } }, [screenIsVisible]) ...}
Бесконечная прокрутка с пагинацией
Вот пример конфигурации запроса getUsers
RTK查詢(摀臉)。 /example
。
// createCache...}=createCache({ ... queries: { getUsers: { query: getUsers, getCacheKey: ()=> 'all-pages', // Для всех страниц используется единый ключ кэша mergeResults: (oldResult, {result: newResult})=> { if (!oldResult || newResult.page===1) { return newResult } if (newResult.page===oldResult.page + 1) { return { ...newResult, items: [...oldResult.items, ...newResult.items], } } return oldResult }, }, }, ...})// Компонентexport const GetUsersScreen=()=> { const [{result: usersResult, loading, error, params}, fetchUsers]=useQuery({ query: 'getUsers', params: 1 // страница }) const refreshing=loading && params===1 const loadingNextPage=loading && !refreshing const onRefresh=()=> fetchUsers() const onLoadNextPage=()=> { const lastLoadedPage=usersResult?.page ?? 0 fetchUsers({ query: 'getUsers', params: lastLoadedPage + 1, }) } const renderUser=(userId: number)=> ( ) ... return ( {refreshing && } {usersResult?.items.map(renderUser)} {loadingNextPage ? ( ) : ( )} )}
還原-持久化
與 redux-persist 相關的內容:
// Удаляет `loading` и `error` из сохраняемого состоянияfunction stringifyReplacer(key: string, value: unknown) { return key==='loading' || key==='error' ? undefined : value}const persistedReducer=persistReducer( { key: 'cache', storage, whitelist: ['entities', 'queries'], // Cостояние мутаций не сохраняем throttle: 1000, // ms serialize: (value: unknown)=> JSON.stringify(value, stringifyReplacer), }, cacheReducer)
WordPress Заключение
Хоть проект и находится на стадии развития, но уже готов к использоаниье готов к исполь Конструктивная критика и квалифицировтивная критика и квалифицировтвуется помощь приветствуется。