Skip to content

Commit

Permalink
Align the store usage to be even closer to solidjs
Browse files Browse the repository at this point in the history
  • Loading branch information
dominikzogg committed Mar 11, 2024
1 parent 74efd21 commit 6d603fc
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 18 deletions.
10 changes: 7 additions & 3 deletions src/component/form/pet-filters-form.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useMemo, type FC } from 'react';
import { useMemo, type FC, useEffect } from 'react';
import type { HttpError } from '../../client/error';
import { createInvalidParametersByName } from '../../client/error';
import { FieldSet, TextField } from './form';
Expand All @@ -19,12 +19,16 @@ export const PetFiltersForm: FC<PetFiltersFormProps> = ({
}: PetFiltersFormProps) => {
const groupInvalidParametersByName = useMemo(() => createInvalidParametersByName(httpError), [httpError]);

const [petFilters, setPetFilters] = useStore<PetFilters>(initialPetFilters);
const [petFilters, setPetFilters, setPetFilterValueByName] = useStore<PetFilters>(initialPetFilters);

const onSubmit = () => {
submitPetFilters({ ...petFilters });
};

useEffect(() => {
setPetFilters(initialPetFilters);
}, [initialPetFilters]);

return (
<form
onSubmit={(e) => {
Expand All @@ -38,7 +42,7 @@ export const PetFiltersForm: FC<PetFiltersFormProps> = ({
data-testid="pet-filters-form-name"
label="Name"
value={petFilters.name ?? ''}
setValue={(value) => setPetFilters('name', value === '' ? undefined : value)}
setValue={(value) => setPetFilterValueByName('name', value === '' ? undefined : value)}
invalidParameters={groupInvalidParametersByName.get('filters[name]') ?? []}
/>
<Button data-testid="pet-filters-form-submit" colorTheme="blue">
Expand Down
20 changes: 13 additions & 7 deletions src/component/form/pet-form.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useMemo, type FC } from 'react';
import { useMemo, type FC, useEffect } from 'react';
import { FieldSet, TextField } from './form';
import type { HttpError } from '../../client/error';
import { createInvalidParametersByName } from '../../client/error';
Expand All @@ -15,12 +15,18 @@ export type PetFormProps = {
export const PetForm: FC<PetFormProps> = ({ submitPet, initialPet, httpError }: PetFormProps) => {
const groupInvalidParametersByName = useMemo(() => createInvalidParametersByName(httpError), [httpError]);

const [pet, setPet] = useStore<PetRequest>(initialPet ?? { name: '', vaccinations: [] });
const [pet, setPet, setPetValueByName] = useStore<PetRequest>({ name: '', vaccinations: [] });

const onSubmit = () => {
submitPet({ ...pet });
};

useEffect(() => {
if (initialPet) {
setPet(initialPet);
}
}, [initialPet]);

return (
<form
onSubmit={(e) => {
Expand All @@ -34,14 +40,14 @@ export const PetForm: FC<PetFormProps> = ({ submitPet, initialPet, httpError }:
data-testid="pet-form-name"
label="Name"
value={pet.name}
setValue={(value) => setPet('name', value)}
setValue={(value) => setPetValueByName('name', value)}
invalidParameters={groupInvalidParametersByName.get('name') ?? []}
/>
<TextField
data-testid="pet-form-tag"
label="Tag"
value={pet.tag ?? ''}
setValue={(value) => setPet('tag', value === '' ? undefined : value)}
setValue={(value) => setPetValueByName('tag', value === '' ? undefined : value)}
invalidParameters={groupInvalidParametersByName.get('tag') ?? []}
/>
<div className="mb-3">
Expand All @@ -55,7 +61,7 @@ export const PetForm: FC<PetFormProps> = ({ submitPet, initialPet, httpError }:
label="Name"
value={vaccination.name}
setValue={(value) =>
setPet('vaccinations', [
setPetValueByName('vaccinations', [
...pet.vaccinations.map((currentVaccination, y) => {
if (y === i) {
return { ...currentVaccination, name: value };
Expand All @@ -73,7 +79,7 @@ export const PetForm: FC<PetFormProps> = ({ submitPet, initialPet, httpError }:
e.preventDefault();
e.stopPropagation();

setPet('vaccinations', [...pet.vaccinations.filter((_, y) => y !== i)]);
setPetValueByName('vaccinations', [...pet.vaccinations.filter((_, y) => y !== i)]);
}}
colorTheme="red"
>
Expand All @@ -88,7 +94,7 @@ export const PetForm: FC<PetFormProps> = ({ submitPet, initialPet, httpError }:
e.preventDefault();
e.stopPropagation();

setPet('vaccinations', [...pet.vaccinations, { name: '' }]);
setPetValueByName('vaccinations', [...pet.vaccinations, { name: '' }]);
}}
colorTheme="green"
>
Expand Down
4 changes: 2 additions & 2 deletions src/component/page/pet/list.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { FC } from 'react';
import { useEffect } from 'react';
import { useEffect, useMemo } from 'react';
import { de } from 'date-fns/locale';
import { format } from 'date-fns';
import { useNavigate, useLocation } from 'react-router-dom';
Expand Down Expand Up @@ -40,7 +40,7 @@ const List: FC = () => {
deleteClient,
});

const query = querySchema.parse(qs.parse(location.search.substring(1)));
const query = useMemo(() => querySchema.parse(qs.parse(location.search.substring(1))), [location]);

const petListRequest: PetListRequest = {
offset: query.page * limit - limit,
Expand Down
10 changes: 5 additions & 5 deletions src/hook/use-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import { useState } from 'react';

export const useStore = <T extends { [key: string]: unknown }>(
initialData: T,
): [T, (name: keyof T, value: T[keyof T]) => void] => {
const [store, replaceStore] = useState<T>(initialData);
): [T, (value: T) => void, (name: keyof T, value: T[keyof T]) => void] => {
const [store, setStore] = useState<T>(initialData);

const setStore = (name: keyof T, value: T[keyof T]): void => {
replaceStore({ ...store, [name]: value });
const setStoreValueByName = (name: keyof T, value: T[keyof T]): void => {
setStore({ ...store, [name]: value });
};

return [store, setStore];
return [store, setStore, setStoreValueByName];
};
8 changes: 7 additions & 1 deletion tests/hook/use-store.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,14 @@ test('useStore', async () => {
expect(result.current[0]).toEqual(dummy);

act(() => {
result.current[1]('key2', 'value22');
result.current[2]('key2', 'value22');
});

expect(result.current[0]).toEqual({ ...dummy, key2: 'value22' });

act(() => {
result.current[1]({ ...dummy, key3: 'value33' });
});

expect(result.current[0]).toEqual({ ...dummy, key3: 'value33' });
});

0 comments on commit 6d603fc

Please sign in to comment.