0

When I cumstom a component that import { DatePicker } from '@material-ui/pickers and if I use Validation => add new Validators,the popup can't render the DatePicker and throw `caught Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:

  1. You might have mismatching versions of React and the renderer (such as React DOM)
  2. You might be breaking the Rules of Hooks
  3. You might have more than one copy of React in the same app andabove error occurred in the component`

my custom component is like this:

import React, { createElement } from 'react';
import { DatePicker } from '@material-ui/pickers';
import { ElementFactory, Question, Serializer, SvgRegistry } from 'survey-core';
import { SurveyQuestionElementBase, ReactQuestionFactory } from 'survey-react-ui';
import { PropertyGridEditorCollection } from 'survey-creator-react';
import { localization } from 'survey-creator-core';
import { ReactComponent as CalendarIcon } from './icons/calendar.svg';
const CUSTOM_TYPE = 'year-picker';
import ReactDOMServer from 'react-dom/server';

export default class QuestionYearPickerModel extends Question {
  getType() {
    return CUSTOM_TYPE;
  }
}
//register `QuestionYearPicker` as a model for the `year-picker` type
export function registerYearPicker() {
  ElementFactory.Instance.registerElement(CUSTOM_TYPE, (name) => {
    return new QuestionYearPickerModel(name);
  });
}

const locale = localization.getLocale('');
locale.qt[CUSTOM_TYPE] = 'Year Picker';

// // Register an SVG icon for the question type
const svg = ReactDOMServer.renderToString(<CalendarIcon />);
SvgRegistry.registerIconFromSvg(CUSTOM_TYPE, svg);

// Add question type metadata for further serialization into JSON
Serializer.addClass(
  CUSTOM_TYPE,
  [],
  function () {
    return new QuestionYearPickerModel('');
  },
  'question',
);

// A class that renders questions of the new type in the UI
export class SurveyQuestionYearPicker extends SurveyQuestionElementBase {
  constructor(props) {
    super(props);
    this.state = { value: this.question.value };
  }
  get question() {
    return this.questionBase;
  }
  get value() {
    return this.question.value;
  }
  handleValueChange = (data) => {
    this.question.value = data;
  };

  // Support the read-only and design modes
  get style() {
    return this.question.getPropertyValue('readOnly') || this.question.isDesignMode
      ? { pointerEvents: 'none' }
      : undefined;
  }

  renderElement() {
    return <div style={this.style}>{renderYearPicker(this.value, this.handleValueChange, this.question)}</div>;
  }
}

export function renderYearPicker(value, handleValueChange, question) {
  return (
    <DatePicker
      label={'Year'}
      openTo="year"
      views={['year']}
      onChange={handleValueChange}
      value={value || null}
      disabled={question.isReadOnly}
    />
  );
}

// Register `SurveyQuestionYearPicker` as a class that renders `year-picker` questions
ReactQuestionFactory.Instance.registerQuestion(CUSTOM_TYPE, (props) => {
  return createElement(SurveyQuestionYearPicker, props);
});

// Register the `year-picker` as an editor for properties of the `year-picker` type in the Survey Creator's Property Grid
PropertyGridEditorCollection.register({
  fit: function (prop) {
    return prop.type === 'year-picker';
  },
  getJSON: function () {
    return {
      type: CUSTOM_TYPE,
    };
  },
});

and the creator is import and registerYearPicker();

Olivier Tassinari
  • 8,238
  • 4
  • 23
  • 23
Hanshan
  • 21
  • 4

0 Answers0