Построение конструктора планов обучения: Работа со сложными формами в Remix

Здравствуйте! В продолжение этой мини-серии я хотел бы поделиться с вами тем, как я работал со сложными формами в Remix. Видите ли, я создаю конструктор учебных планов, который в настоящее время выглядит следующим образом

Remix ожидает, что вы будете обрабатывать данные, отправленные на бэкенд, с помощью actions. Это довольно здорово, когда вы имеете дело с простыми формами, но здесь у меня есть эти столбцы, и в каждом столбце несколько упражнений, поэтому было бы здорово, если бы я мог как-то сгруппировать данные.

Первой идеей было сделать это так, как описано в документации, то есть примерно так

export const action = async ({ request }) => {
  const formData = await request.formData();

  const title = formData.get("title");
  const slug = formData.get("slug");
  const markdown = formData.get("markdown");
  ...
}
Войти в полноэкранный режим Выйти из полноэкранного режима

Таким образом я бы как-то вызывал Object.entries на formData, давая входным данным имена типа col-1-ex-1. Вы можете представить, насколько это было бы утомительно. Поэтому я искал решение и нашел довольно умное решение с помощью пакета qs (querystring).

Благодаря этому пакету я могу давать каждому из входов упражнения такие имена, как

  • фазы[${idx}][${exercise.id}][название]
  • фазы[${idx}][${exercise.id}][sets]
  • фазы[${idx}][${exercise.id}][повторения]

который, после разбора запроса, содержит такой фрагмент

export const action: ActionFunction = async ({ request }) => {
  const text = await request.text();
  const parsed = qs.parse(text) as YourCustomType

  ...
}
Войти в полноэкранный режим Выйти из полноэкранного режима

дает следующую структуру

phases: [
  {
     exerciseId: { 
        sets: number,
        reps: number,
        title: string,
     },
     exerciseId2: { 
        sets: number,
        reps: number,
        title: string,
     }
  },
  {
     exerciseId3: { 
        sets: number,
        reps: number,
        title: string,
     }
  },
  {
     exerciseId4: { 
        sets: number,
        reps: number,
        title: string,
     },
     exerciseId5: { 
        sets: number,
        reps: number,
        title: string,
     }
  },
] // 3 objects represent 3 columns (phases) in the app
Войти в полноэкранный режим Выйти из полноэкранного режима

С этой структурой гораздо проще работать. И самое приятное, что я получил эту структуру, используя всего две строки кода 😅.

Спасибо за прочтение и надеюсь, что это кому-то поможет! Берегите себя 😉

Исходный код -> Strongion

Исходный поток -> обсуждение на github

Оцените статью
devanswers.ru
Добавить комментарий