Как визуализировать поля формы на лету (не предопределено), чтобы получить контролируемые поля в React.js - PullRequest
0 голосов
/ 15 мая 2019

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

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

Одна из проблем текущего решения заключается в том, что асинхронность setState приводит к тому, что начальное значение полей не определено.

Я добавил свойство состояния «рендеринг», чтобы оно отличалось от начального рендеринга и рендеринга, вызванного обновлением поля, но это грязный взлом, а не решение.

class Forms extends React.Component<any, any> {
  constructor(props: any) {
    super(props);
  }

  state = { rendering: true, fields: [] }

  shouldComponentUpdate(nextProps, nextState) {
    return !this.state.rendering || this.props !== nextProps;
  }

  onChange = (e) => {
    const { target } = e;
    const value = target.type === 'checkbox' ? target.checked : target.value;
    this.setState({ [target.name]: value });
  }

  renderFormComponents = (props) => {
    const fields = [];
    const { components, pageId } = props;
    const renderedComponents = components.map((component, index) => {
      const componentId = component.value.value.guid;

      if (this.state.rendering) {
        this.setState({ [componentId]: "" });
      }
      fields.push(componentId);
      return <FormInput key={componentId} {...component.value.value} value={this.state[componentId]} onChange={this.onChange} />;
    });

    if (this.state.rendering) {
      this.setState({ fields, rendering: false });
    }

    return renderedComponents;
  };

  render() {
    return (
      <ContentGrid
        sections={this.props.value.sections}
        componentType="form-grid"
        pageId={this.props.pageId}
        customRenderComponents={this.renderFormComponents}
      />
    );
  }
}

Рабочий пример здесь: https://codepen.io/ttanathoss/project/editor/DQGzzn

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

И еще одна вещь - я должен добавить валидацию к форме, и каждое поле может иметь свои собственные определенные правила. Я думал о методах проверки, определенных на уровне полей, а затем о методе formValidation, определенном на уровне формы, который вызывает проверку каждого поля, но не могу понять, как правильно его реализовать.

...