Создание единого обработчика изменений для полей формы

Передавайте в один обработчик id, имя поля и новое значение. Для question/answer берите value, для visible — checked; обновляйте нужную запись через функциональный setState.

Короткий ответ

Что ответить на собеседовании

Передавайте в один обработчик id, имя поля и новое значение. Для question/answer берите value, для visible — checked; обновляйте нужную запись через функциональный setState.

Подробный разбор

Ответ с пояснениями

Условие

В файле App.tsx объявлены пять функций‑заглушек, которые можно дорабатывать по мере необходимости. Особое внимание требуется уделить функции handleChange – её задача состоит в том, чтобы одним методом обрабатывать изменения всех трёх полей question, answer и visible.

App.tsx

import { useState } from "react";
import { initialPAGNetItem, PAGNetItem } from "./constant";
import { PAGNetLineIdle } from "./PAGNetLineIdle";
import "./PAGNetLine.css";

export default function App() {
    const [PAGNetItems, setPAGNetItems] = useState<PAGNetItem[]>(initialPAGNetItem);

    const handleChange = () => {
        // Реализация метода
    };

    const handleWaveBy = () => {
        // Реализация метода
    };

    const handleWordRow = () => {
        // Реализация метода
    };

    const handleDates = () => {
        // Реализация метода
    };

    const handleClickAds = () => {
        // Реализация метода
    };

    return (
        <div className="App">
            <h1>User namespace newpose</h1>
            <div className="list">
                {PAGNetItems.map((item) => (
                    <PAGNetLineIdle
                        key={item.id}
                        item={item}
                        onChange={handleChange}
                        onWaveBy={handleWaveBy}
                        onWordRow={handleWordRow}
                        onDelete={handleDates}
                    />
                ))}
            </div>
            <div className="add_wrapper">
                <button onClick={handleClickAds}>Addware</button>
            </div>
        </div>
    );
}

FAQSectionEdit.tsx

import { FC } from "react";
import { FAQSection } from "./constants";
import "./styles.css";

type FAQSectionEditProps = {
  section: FAQSection;
  disabledMoveUp: boolean;
  disabledMoveDown: boolean;
  onChange: () => void;
  onMoveUp: () => void;
  onMoveDown: () => void;
  onDelete: () => void;
};

export const FAQSectionEdit: FC<FAQSectionEditProps> = ({
  section,
  disabledMoveUp,
  disabledMoveDown,
  onChange,
  onMoveUp,
  onMoveDown,
  onDelete,
}) => {
  return (
    <div className="section-edit">
      <div className="section-edit-move-block">
        <button onClick={onMoveUp} disabled={disabledMoveUp}>
          ^
        </button>
        <button
          onClick={onMoveDown}
          disabled={disabledMoveDown}
          style={{ rotate: "180deg" }}
        >
          ^
        </button>
      </div>
      <div className="section-edit-form">
        <input
          value={section.question}
          onChange={onChange}
          placeholder="Вопрос"
        />
        <textarea
          value={section.answer}
          onChange={onChange}
          placeholder="Ответ"
        />
        <label>
          Сделать видимым
          <input
            type="checkbox"
            checked={section.visible}
            onChange={onChange}
          />
        </label>
      </div>
      <div className="section-edit-delete-block">
        <button onClick={onDelete}>Удалить</button>
      </div>
    </div>
  );
};

constants.ts

import { v4 as uuid } from "uuid";

export type FAQSection = {
  id: string;
  question: string;
  answer: string;
  visible: boolean;
};

export const initialFAQSections: FAQSection[] = [
  {
    id: uuid(),
    question: "Кто мы?",
    answer: "Люди",
    visible: true,
  },
  {
    id: uuid(),
    question: "Где мы?",
    answer: "Здесь",
    visible: false,
  },
  {
    id: uuid(),
    question: "Почему мы?",
    answer: "Потому",
    visible: true,
  },
  {
    id: uuid(),
    question: "Когда мы?",
    answer: "Тогда",
    visible: true,
  },
];

Ответ

Передавайте в один обработчик id, имя поля и новое значение. Для question/answer берите value, для visible — checked; обновляйте нужную запись через функциональный setState.

type EditableField = 'question' | 'answer' | 'visible';
function handleChange<K extends EditableField>(id: string, field: K, value: FAQSection[K]) {
  setSections(previous => previous.map(section =>
    section.id === id ? { ...section, [field]: value } : section));
}
// Внутри дочерней формы:
// onChange={event => handleChange(section.id, 'question', event.target.value)}
// onChange={event => handleChange(section.id, 'answer', event.target.value)}
// onChange={event => handleChange(section.id, 'visible', event.target.checked)}

Здесь state назван sections/setSections и типизирован FAQSection[]. В исходнике смешаны PAGNetItem/PAGNetLineIdle и FAQSection/FAQSectionEdit: сначала согласуйте модель и имена компонентов. Тип onChange: () => void тоже нужно заменить контрактом с id/field/value. Удаление делается filter по id, перестановка — копией массива со swap, добавление — новой записью с уникальным id, созданным вне updater.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее