Попытка построить общий компонент формы в React без использования eval () - PullRequest
0 голосов
/ 29 января 2019

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

Моя главная цель здесь - иметь компонент <BasicForm>, который я могу потреблять,передавая функцию отправки как props и передавая поля ввода и кнопки как children с требованиями проверки для каждого поля.

Мой <BasicForm> компонент должен обрабатывать форму state, onChange,onBlur, onSubmit и т. Д. И должен также обрабатывать проверку (на основе каждого типа ввода, который я добавляю как children).

Мотивация заключалась в том, что я каждый раз ощущал повторение, необходимое для созданияновая форма, с необходимостью управлять state для входных данных, проверки, onChange и submit функций снова и снова.

Вот код, где я потребляю <Basic Form>:

BasicForm-Consumer.js

  <BasicForm
    submitFunction={props.linkEmailAndPassword}
    submitAction={'this.props.submitFunction(this.state.passwordOne)'}
    >
    <PasswordInput
      labelText='Password'
      name='passwordOne'
      placeholder='Enter password...'
      min={6}
      max={12}
      required
    />
    <TextInput
      labelText='Username'
      name='username'
      placeholder='Enter username...'
      initialValue=''
      min={5}
      max={10}
      required
    />
    <button type='submit'>Create Password</button>
  </BasicForm>

Я изначально не добавляю сюда исходный код для <BasicForm>, чтобы этот вопрос не был слишком длинным, но в основном он обрабатывает всевход children с React.Children.map и чкак функции проверки для каждого вида ввода, а также функции для обработки изменений, размытия, отправки и т. д. Он также создает state для каждого поля ввода.

QUESTION INTRO

  <BasicForm
    submitFunction={props.linkEmailAndPassword}
    submitAction={'this.props.submitFunction(this.state.passwordOne)'}
  >

Как видно из приведенного выше фрагмента, чтобы отправить submitAction от потребителя на <BasicForm>, я должен заключить его в строку, так как он ссылается на state, который будетсуществуют только внутри <BasicForm>.И самое главное, конкретная state часть, которую мне нужно отправить, определяется вне <BasicForm> (у потребителя).

Потребитель определяет, какая часть или части state должны быть отправленыи оно будет отличаться в каждом случае, поэтому я не могу сделать его «родовым» state именем, которое любое <BasicForm> будет иметь в качестве встроенного.

Так что я отправляю какстрока и внутри <BasicForm> Мне пришлось использовать наиболее НЕ РЕКОМЕНДУЕМЫЕ eval(), как вы можете видеть ниже:

BasicForm.js

  onSubmit(event) {
    event.preventDefault();
    this.validateAllFields();
    eval(this.props.submitAction);
  }

Правильный вопрос

Насколько плохо eval() в этом случае?Делая это, я подвергаю свое приложение «злонамеренным хакерам»?Должен ли я санировать его каким-либо образом, даже если это не ввод пользователя?Есть ли другой способ обойти это?Я действительно счастлив, что мне не нужно создавать форму с нуля каждый раз, когда она мне нужна.Теперь я просто сфокусируюсь на полях и требованиях к валидации.Спасибо за ваше время!

ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ

PS: Вот код для одного из компонентов ввода TextInput.PasswordInput очень похоже на это.Единственная разница - type='password':

TextInput.js

import React from 'react';
import Label from './Common/Label';

const TextInput = (props) => {
  return(
    <div>
      <Label
        name={props.name}
        labelText={props.labelText}
      >
      </Label>
      <div>
      <input
        type='text'
        id={props.name}
        name={props.name}
        placeholder={props.placeholder}
        value={props.value}
        onChange={props.onChange}
        onBlur={props.onBlur}
      >
      </input>
      </div>
      {props.isInvalidMsg && <div><span>{props.isInvalidMsg}</span></div>}
    </div>
  );
};

export default TextInput;

1 Ответ

0 голосов
/ 29 января 2019

Eval почти никогда не приветствуется, поскольку он создает риски для безопасности, снижает производительность и указывает на наличие проблем проектирования.

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

В этом случае это означает, что BasicForm не удалось предоставить разумный API для родительских компонентов, поэтому в итоге получилось eval.Правильный способ сделать это - обратный вызов.

Поскольку родительский компонент вообще не должен знать о BasicForm деталях реализации и обращаться к его экземпляру, BasicForm this не должен быть доступен в обратном вызове.BasicForm реквизиты уже доступны в обратном вызове - они передаются в родительский компонент.Поскольку известно, что BasicForm state содержит значения из своих дочерних входов, он должен быть доступен в обратном вызове.

Так что обратный вызов BasicForm может выглядеть следующим образом:

  <BasicForm
    onSubmit={state => props.linkEmailAndPassword(state.passwordOne)}}

  ...

  onSubmit(event) {
    event.preventDefault();
    this.validateAllFields();
    this.props.onSubmit(this.state);
  }

В случаесуществует необходимость в onSubmit обратном вызове для доступа к любым BasicForm данным, кроме их состояния, это означает, что эти данные также должны быть переданы в качестве аргумента обратного вызова.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...