ステート管理
アプリケーションステート
アプリ全体に渡って保持するステートです。 アプリケーションステートの仕組みとしてAppStateフックを用意しています。
// 引数はキーと初期値。戻り値は[値, セッター]
const useUser = () => useAppState('user', new User(...));
今回のアプリではサインイン済みのユーザーをアプリケーションステートとして保持して、どの機能からでもユーザーステートにアクセスできるようにします。 ユーザーステートへのアクセスにはUserフックを使います。
const [user, setUser] = useUser();
// ユーザーの設定
setUser(new User(...));
// ユーザーの参照
user.id
user.name
user.avatarUrl
サーバーステート
API呼び出しで取得したアプリデータのステートです。 サーバーステートにはReact Queryを使います。
APIにはGraphQLを使い、React Queryを使ったAPI呼び出しのコードは自動生成します。 そのため、アプリ実装ではReact QueryのuseQueryやuseMutationを直接呼び出すことはありません。 データ更新後はQueryClient.invalidateQueriesを呼び出しキャッシュを更新します。
// データ取得
const [user] = useUser();
const graphQLClient = useGraphQLClient();
const { data: findGroupsQuery } = useFindGroupsQuery(graphQLClient, {
userId: user.id,
});
// データ更新
const graphQLClient = useGraphQLClient();
const changeGroupMutation = useChangeGroupMutation(graphQLClient);
const queryClient = useQueryClient();
const submit = async (values: typeof form.values) => {
const input = { ...values };
const onSuccess = async () => {
await queryClient.invalidateQueries([
'findGroups',
{ userId: user.id },
]);
};
await changeGroupMutation.mutateAsync({ groupId, input }, { onSuccess });
};
コンポーネントステート
ページやモーダル単位のステートはMantineのuse-set-stateを使います。
const [state, setState] = useSetState({
addGroupOpened: false,
changeMembersOpened: false,
changeGroupOpened: false,
removeGroupOpened: false,
groupId: -1,
});
setState({ addGroupOpened: true })
フォームステート
入力フォームのステートはMantineのuse-formを使います。
const form = useForm({
initialValues: {
name: '',
},
});
const submit = async (values: typeof form.values) => {
// valuesを使った処理
};
<form onSubmit={form.onSubmit(submit)} noValidate>
<TextInput
required
type="text"
label={t('name')}
description={t('group.name.description')}
{...form.getInputProps('name')}
/>
<Group position="right" mt="md">
<Button type="submit" size="sm">
{t('add')}
</Button>
</Group>
</form>