2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

内容編集後に配列が入れ替わってしまう問題の解消

Posted at

はじめに

登録した内容を編集できる機能を実装した際、保存時にデータが再取得されて順番が入れ替わる問題が発生したので、解決した方法をまとめます。

問題

学習内容を登録後、内容を編集すると登録した順番が入れ替わる。

原因

更新後(保存後)にfetchTodos()を呼んでいて、Supabase から再取得したデータが順序保証のない状態で返ってきているのが原因でした。

解決方法

Supabase側でcreated_atを追加し、登録日時で順番を制御する手も考えましたが、手間がかかりそうだったので id 一致要素だけ差し替えるローカル更新で編集成功時に**差し替え(上書き)**だけ行い、再取得をしないようにして配列の順序を維持しました。

データ再取得用
  useEffect(() => {
    fetchTodos();
  }, []);
before
  const updateRecordCore = async (
    id: string,
    values: LearningFormValues
  ): Promise<boolean> => {
    const { records, time, remark } = values;
    setIsLoading(true);
    const result = await updateHistory(id, records, time!, remark);
    if (result !== undefined) {
      await fetchTodos();
      resetFormState();
      setIsLoading(false);
      return true;
      // 以降エラー処理
after
  const updateRecordCore = async (
    id: string,
    values: LearningFormValues
  ): Promise<boolean> => {
    const { records, time, remark } = values;
    setIsLoading(true);
    const result = await updateHistory(id, records, time!, remark);
    if (result !== undefined) {
      // 以下のように修正
      setHistoryRecordss((prev) => prev.map((r) => (r.id === id ? result : r)));
      resetFormState();
      setIsLoading(false);
      return true;
      // 以降エラー処理

map
└ 配列全体をコピーしつつ、対象だけを差し替える、不変更新の王道パターン。

条件式 (r.id === id ? result : r)
└ id が一致した要素はr = resultに置き換え、それ以外はそのまま返す。

おわりに

関数型アップデートのいい復習になりました。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?