ホームページ  >  記事  >  ウェブフロントエンド  >  楽観的な更新を使用したデータテーブルの構築

楽観的な更新を使用したデータテーブルの構築

DDD
DDDオリジナル
2024-11-04 07:28:01977ブラウズ

導入

今日は、最新の React パターンを使用して洗練された食品データベース管理システムを構築した方法を共有します。 TanStack Query (旧称 React Query) の機能と Mantine のコンポーネント ライブラリを組み合わせて、シームレスで楽観的な更新を行う応答性の高いデータ テーブルを作成することに重点を置きます。

プロジェクト概要

要件

  • 食品項目をデータテーブルに表示する
  • 即時フィードバックで新しいアイテムを追加
  • 読み込み状態とエラー状態を適切に処理します
  • スムーズで楽観的なアップデートを提供します

技術スタック

  • TanStack クエリ: サーバー状態管理
  • Mantine UI: コンポーネント ライブラリとフォーム管理
  • Mantine React テーブル: 高度なテーブル機能
  • 最悪: クリーンな API 呼び出し
  • TypeScript: タイプ セーフティ

実装ガイド

1. 財団の設立

まず、タイプと API 構成を定義しましょう:

// Types
export type GetAllFoods = {
  id: number;
  name: string;
  category: string;
};

export type CreateNewFoodType = Pick<
  GetAllFoods,
  | 'name'
  | 'category'
>;

// API Configuration
export const API = wretch('<http://localhost:9999>').options({
  credentials: 'include',
  mode: 'cors',
  headers: {
    'Content-Type': 'application/json',
    Accept: 'application/json',
  },
});

// TANSTACK QUERY 
export const getFoodOptions = () => {
  return queryOptions({
    queryKey: ['all-foods'],
    queryFn: async () => {
      try {
        return await API.get('/foods')
          .unauthorized(() => {
            console.log('Unauthorized');
          })
          .json<Array<GetAllFoods>>();
      } catch (e) {
        console.log({ e });
        throw e;
      }
    },
  });
};

export const useGetAllFoods = () => {
  return useQuery({
    ...getFoodOptions(),
  });
};

2. データテーブルの構築

Mantine React Table を使用したテーブル コンポーネント:

const FoodsView = () => {
  const { data } = useGetAllFoods();

  const columns = useMemo<MRT_ColumnDef<GetAllFoods>[]>(
    () => [
      {
        accessorKey: 'id',
        header: 'ID',
      },
      {
        accessorKey: 'name',
        header: 'Name',
      },
      {
        accessorKey: 'category',
        header: 'Category',
      },
      // ... other columns
    ],
    []
  );

  const table = useMantineReactTable({
    columns,
    data: data ?? [],
    // Optimistic update animation
    mantineTableBodyCellProps: ({ row }) => ({
      style: row.original.id < 0 ? {
        animation: 'shimmer-and-pulse 2s infinite',
        background: `linear-gradient(
          110deg,
          transparent 33%,
          rgba(83, 109, 254, 0.2) 50%,
          transparent 67%
        )`,
        backgroundSize: '200% 100%',
        position: 'relative',
      } : undefined,
    }),
  });

  return <MantineReactTable table={table} />;
};

3. フォームの作成

新しい食べ物を追加するためのフォームコンポーネント:

const CreateNewFood = () => {
  const { mutate } = useCreateNewFood();

  const formInputs = [
    { name: 'name', type: 'text' },
    { name: 'category', type: 'text' },
  ];

  const form = useForm<CreateNewFoodType>({
    initialValues: {
      name: '',
      category: '',
      // ... other fields
    },
  });

  return (
    <Box mt="md">
      <form onSubmit={form.onSubmit((data) => mutate(data))}>
        <Flex direction="column" gap="xs">
          {formInputs.map((input) => (
            <TextInput
              key={input.name}
              {...form.getInputProps(input.name)}
              label={input.name}
              tt="uppercase"
              type={input.type}
            />
          ))}
          <Button type="submit" mt="md">
            Create New
          </Button>
        </Flex>
      </form>
    </Box>
  );
};

4. 楽観的なアップデートの実装

実装の中心 - TanStack Query のミューテーションと楽観的な更新:

export const useCreateNewFood = () => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationKey: ['create-new-food'],
    mutationFn: async (data: CreateNewFoodType) => {
      await new Promise(resolve => setTimeout(resolve, 3000)); // Demo delay
      return API.url('/foods').post(data).json<GetAllFoods>();
    },
    onMutate: async (newFood) => {
      // Cancel in-flight queries
      await queryClient.cancelQueries({ queryKey: ['all-foods'] });

      // Snapshot current state
      const previousFoods = queryClient.getQueryData<GetAllFoods[]>(['all-foods']);

      // Create optimistic entry
      const optimisticFood: GetAllFoods = {
        id: -Math.random(),
        ...newFood,
        verified: false,
        createdBy: 0,
        createdAt: new Date().toISOString(),
        updatedAt: new Date().toISOString(),
      };

      // Update cache optimistically
      queryClient.setQueryData(['all-foods'], (old) =>
        old ? [...old, optimisticFood] : [optimisticFood]
      );

      return { previousFoods };
    },
    onError: (err, _, context) => {
      // Rollback on error
      if (context?.previousFoods) {
        queryClient.setQueryData(['all-foods'], context.previousFoods);
      }
    },
    onSettled: () => {
      // Refetch to ensure consistency
      queryClient.invalidateQueries({ queryKey: ['all-foods'] });
    },
  });
};

5. アニメーションスタイル

私たちの楽観的な最新情報を実現するアニメーション:

@keyframes shimmer-and-pulse {
  0% {
    background-position: 200% 0;
    transform: scale(1);
    box-shadow: 0 0 0 0 rgba(83, 109, 254, 0.2);
  }
  50% {
    background-position: -200% 0;
    transform: scale(1.02);
    box-shadow: 0 0 0 10px rgba(83, 109, 254, 0);
  }
  100% {
    background-position: 200% 0;
    transform: scale(1);
    box-shadow: 0 0 0 0 rgba(83, 109, 254, 0);
  }
}

ベストプラクティス

  1. 楽観的な最新情報
    • UI をすぐに更新して UX を向上させます
    • ロールバックでエラーケースを処理する
    • 適切な無効化によりデータの一貫性を維持します
  2. タイプセーフティ
    • 保守性を向上させるために TypeScript を使用します
    • データ構造の明確なインターフェイスを定義
    • 可能な場合は型推論を利用します
  3. パフォーマンス
    • 更新中に実行中のクエリをキャンセルします
    • 適切なクエリ無効化を使用する
    • 効率的なフォーム状態管理の実装
  4. ユーザーエクスペリエンス
    • すぐにフィードバックを提供します
    • 読み込み状態を表示
    • エラーを適切に処理します

将来の機能強化

実装に向けて次の改善点を検討してください。

  • 元に戻す/やり直し機能
  • フォーム検証ルール
  • エラー境界の実装

結果

Building a Data Table with Optimistic Updates

完了したリクエスト

Building a Data Table with Optimistic Updates

結論

この実装では、最新の React パターンを使用して堅牢なデータ管理システムを作成する方法を示します。 TanStack Query、Mantine UI、思慮深い楽観的なアップデートの組み合わせにより、スムーズでプロフェッショナルなユーザー エクスペリエンスが生み出されます。

次のことを忘れないでください:

  • コンポーネントに焦点を当てて保守しやすい状態に保ちます
  • すべての可能な状態 (読み込み、エラー、成功) を処理します
  • コードの品質を向上させるには TypeScript を使用します
  • 実装時にユーザー エクスペリエンスを考慮する

React アプリケーションにオプティミスティック アップデートを実装する際に、どのような課題に直面しましたか?以下のコメント欄であなたの経験を共有してください。

以上が楽観的な更新を使用したデータテーブルの構築の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。