kopia lustrzana https://gitlab.com/soapbox-pub/soapbox
EntityStore: parse entities after fetch, not during render (performance)
rodzic
e9ae8d2c45
commit
a19b1e83a9
|
@ -3,6 +3,7 @@ import z from 'zod';
|
||||||
|
|
||||||
import { getNextLink, getPrevLink } from 'soapbox/api';
|
import { getNextLink, getPrevLink } from 'soapbox/api';
|
||||||
import { useApi, useAppDispatch, useAppSelector } from 'soapbox/hooks';
|
import { useApi, useAppDispatch, useAppSelector } from 'soapbox/hooks';
|
||||||
|
import { filteredArray } from 'soapbox/schemas/utils';
|
||||||
|
|
||||||
import { entitiesFetchFail, entitiesFetchRequest, entitiesFetchSuccess } from '../actions';
|
import { entitiesFetchFail, entitiesFetchRequest, entitiesFetchSuccess } from '../actions';
|
||||||
|
|
||||||
|
@ -52,10 +53,9 @@ function useEntities<TEntity extends Entity>(
|
||||||
|
|
||||||
const entities: readonly TEntity[] = entityIds ? (
|
const entities: readonly TEntity[] = entityIds ? (
|
||||||
Array.from(entityIds).reduce<TEntity[]>((result, id) => {
|
Array.from(entityIds).reduce<TEntity[]>((result, id) => {
|
||||||
// TODO: parse after fetch, not during render.
|
const entity = cache?.store[id];
|
||||||
const entity = schema.safeParse(cache?.store[id]);
|
if (entity) {
|
||||||
if (entity.success) {
|
result.push(entity as TEntity);
|
||||||
result.push(entity.data);
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}, [])
|
}, [])
|
||||||
|
@ -74,7 +74,9 @@ function useEntities<TEntity extends Entity>(
|
||||||
dispatch(entitiesFetchRequest(entityType, listKey));
|
dispatch(entitiesFetchRequest(entityType, listKey));
|
||||||
try {
|
try {
|
||||||
const response = await api.get(url);
|
const response = await api.get(url);
|
||||||
dispatch(entitiesFetchSuccess(response.data, entityType, listKey, {
|
const entities = filteredArray(schema).parse(response.data);
|
||||||
|
|
||||||
|
dispatch(entitiesFetchSuccess(entities, entityType, listKey, {
|
||||||
next: getNextLink(response),
|
next: getNextLink(response),
|
||||||
prev: getPrevLink(response),
|
prev: getPrevLink(response),
|
||||||
fetching: false,
|
fetching: false,
|
||||||
|
|
|
@ -30,11 +30,7 @@ function useEntity<TEntity extends Entity>(
|
||||||
const defaultSchema = z.custom<TEntity>();
|
const defaultSchema = z.custom<TEntity>();
|
||||||
const schema = opts.schema || defaultSchema;
|
const schema = opts.schema || defaultSchema;
|
||||||
|
|
||||||
const entity = useAppSelector(state => {
|
const entity = useAppSelector(state => state.entities[entityType]?.store[entityId] as TEntity | undefined);
|
||||||
// TODO: parse after fetch, not during render.
|
|
||||||
const result = schema.safeParse(state.entities[entityType]?.store[entityId]);
|
|
||||||
return result.success ? result.data : undefined;
|
|
||||||
});
|
|
||||||
|
|
||||||
const [isFetching, setIsFetching] = useState(false);
|
const [isFetching, setIsFetching] = useState(false);
|
||||||
const isLoading = isFetching && !entity;
|
const isLoading = isFetching && !entity;
|
||||||
|
@ -42,7 +38,8 @@ function useEntity<TEntity extends Entity>(
|
||||||
const fetchEntity = () => {
|
const fetchEntity = () => {
|
||||||
setIsFetching(true);
|
setIsFetching(true);
|
||||||
api.get(endpoint).then(({ data }) => {
|
api.get(endpoint).then(({ data }) => {
|
||||||
dispatch(importEntities([data], entityType));
|
const entity = schema.parse(data);
|
||||||
|
dispatch(importEntities([entity], entityType));
|
||||||
setIsFetching(false);
|
setIsFetching(false);
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
setIsFetching(false);
|
setIsFetching(false);
|
||||||
|
|
Ładowanie…
Reference in New Issue