@EvgenJunior

Как написать одну функцию для 4 разных компонентов?

Добрый день!
Я использую при создании приложения React, Material UI. Я создал кастомный компонент на основание TextField из Material UI. CustomTextField используется 4 раза в компоненте, следовательно я создал 4 обработчика, которые изменяют state. Мне не нравится, то что у меня 4 одинаковых функции, которые выполняют одно и тоже действие. Подскажите пожалуйста как мне сделать одну функцию для 4 разных CustomTextField. Есть решение с помощью Switch case. Хотел бы еще какие-нибудь варианты.
P.S. или это нормально когда у меня 4 разных компонента , каждый со своим state и обработчиком событий?
const [firstName, setFirstName] = useState<string>('');
  const [lastName, setLastName] = useState<string>('');
  const [dept, setDept] = useState<string>('');
  const [login, setLogin] = useState<string>('');

const onChangeFirstName = (event: React.ChangeEvent<HTMLInputElement>) => {
    setFirstName(event.target.value);
  };
  const onChangeLastName = (event: React.ChangeEvent<HTMLInputElement>) => {
    setLastName(event.target.value);
  };
  const onChangeDept = (event: React.ChangeEvent<HTMLInputElement>) => {
    setDept(event.target.value);
  };
  const onChangeLogin = (event: React.ChangeEvent<HTMLInputElement>) => {
    setLogin(event.target.value);
  };

<CustomTextField
            onChange={onChangeDept}
</CustomTextField>
<CustomTextField
            onChange={onChangeLogin}
</CustomTextField>
<CustomTextField
            onChange={onChangeFirstName}
</CustomTextField>
<CustomTextField
            onChange={onChangeLastName}
</CustomTextField>
  • Вопрос задан
  • 152 просмотра
Решения вопроса 2
0xD34F
@0xD34F Куратор тега React
Вместо нескольких стейтов пусть будет один - объект. Общий обработчик onChange достаёт из целевого объекта помимо значения ещё и имя инпута, одновременно являющегося именем обновляемого свойства (его придётся передавать в экземпляры CustomTextField, а внутри самого CustomTextField прокидывать внутрь TextField). Вот так (как добавить два других свойства - думаю, сами догадаетесь):

interface IFormData {
  firstName: string;
  lastName: string;
}

const [ formData, setFormData ] = React.useState<IFormData>({
  firstName: '',
  lastName: '',
});

const onChange = (e: React.ChangeEvent<HTMLInputElement>) => setFormData({
  ...formData,
  [e.target.name]: e.target.value,
});

<CustomTextField name="firstName" value={formData.firstName} onChange={onChange} />
<CustomTextField name="lastName" value={formData.lastName} onChange={onChange} />

<!-- или -->

{Object.entries(formData).map(([ k, v ]) => (
  <CustomTextField key={k} name={k} value={v} onChange={onChange} />
))}
Ответ написан
Комментировать
bingo347
@bingo347 Куратор тега TypeScript
Crazy on performance...
// хелперы
const makeCustomTextFieldWithState = (): [string, ReactElement] => {
  const [value, setValue] = useState<string>('');
  const onChange = (event: React.ChangeEvent<HTMLInputElement>) =>
    setValue(event.target.value);
  return [value, <CustomTextField onChange={onChange} />];
};

const makeManyCustomTextFieldWithState = (count: number): [string[], ReactElement[]] =>
  Array(count).fill(0).reduce(([values, elements]) => {
    const [value, element] = makeCustomTextFieldWithState();
    return [
      [...values, value],
      [...elements, element],
    ];
  }, [[], []]);

// в компоненте
const [[dept, login, firstName, lastName], elements] = makeManyCustomTextFieldWithState(4);
<>{elements}</>
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
Kentavr16
@Kentavr16
long cold winter
Это вполне нормально. Сравните читаемость кода с 4 обработчиками и другие варианты. Зачем усложнять? На js мы вроде стремимся к декларативному подходу в программировании. Меньший код не равно опттмальный код
Ответ написан
sarapinit
@sarapinit
Точу водой камень
Мне не нравится, то что у меня 4 одинаковых функции, которые выполняют одно и тоже действие. Подскажите пожалуйста как мне сделать одну функцию для 4 разных CustomTextField.

Не усложняйте.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы