Проверка настраиваемого поля формы с помощью Formik, React - PullRequest
0 голосов
/ 04 августа 2020

Я использую Formik и Yup для проверки моей формы,

Я использую настраиваемое поле формы ( мгновенный поиск Algolia ) в своей форме, но я не могу проверить

Я попробовал 2 варианта, я думаю, что вариант 2 многообещающий, но есть проблема.

Вариант 1: Как вы можете видеть ниже, я попытался обернуть поле настраиваемой формы (<AlgoliaSearch />) в форму как и с полем номера мобильного телефона, чтобы добиться аналогичной проверки. Оказывается, это не работает, т.е. сообщение об ошибке появляется, даже когда поле заполнено.

Вариант 2: когда пользователь устанавливает значение в настраиваемом поле формы (<AlgoliaSearch />), я устанавливаю то же значение в стандартном поле ввода (в приведенном ниже коде найдите СТАНДАРТНОЕ ПОЛЕ ВВОДА), когда я нажимаю кнопку «Отправить», formik не распознает, что поле (СТАНДАРТНОЕ ПОЛЕ ВВОДА) заполнено (хотя оно было заполнено программно). Вероятно, это связано с тем, что formik предполагает, что, поскольку поле не было затронуто, поэтому оно не было заполнено. Чтобы исправить это, мне нужно знать, как я могу программно установить, что поле было затронуто, используя Formik .

In form. js

const [selectedValue, setSelectedValue] = React.useState('');
  const handleSearchValue = _selectedVlue => {
    console.log(_selectedValue);
    setSelectedValue(_selectedValue);
  };

const validationSchema = Yup.object({
mobileNumber: Yup.string()
  .required()
  .min(10)
  .label('Mobile number'),
searchValue: Yup.string()
  .required()
  .label('Search value'),
selectedValue: Yup.string()
  .required()
  .label('Selected value')

return (
<>
  <Formik
    initialValues={{
      mobileNumber: '',
      searchValue: '',
      selectedValue:''
    }}
    onSubmit={handleSubmit}
    validationSchema={validationSchema}
    setFieldTouched={('selectedDoctor', true, true)}
  >
    <Form style={{ maxWidth: '250px', margin: '50px' }}>
     
      <Form.Item name="mobileNumber" hasFeedback={true} showValidateSuccess={true}>
        <Text>Mobile number</Text>
        <Input
          size="large"
          name="mobileNumber"
        />
      </Form.Item>

      {/* CUSTOM FORM FIELD */}
      <Form.Item name="searchValue" hasFeedback={true} showValidateSuccess={true}>
        <AlgoliaSearch searchValue={handleSearchValue} />
      </Form.Item>
      
      {/* STANDARD INPUT FIELD */}
      <Form.Item name="selectedValue" hasFeedback={true} showValidateSuccess={true}>
        <Input name="selectedValue" value={selectedValue} user />
      </Form.Item
    </Form>
 </Formik>
</>
);

AlgoliaSearch. js

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import algoliasearch from 'algoliasearch/lite';
import { InstantSearch, Configure, Hits, Highlight, connectSearchBox } from 'react-instantsearch-dom';
import Autocomplete from './Autocomplete';
import './Algolia.css';

// References
// Github, Autocomplete code: https://github.com/algolia/doc-code-samples/tree/master/React%20InstantSearch/autocomplete-results-page/src
// Algolia, autocomplete explained: https://www.algolia.com/doc/guides/building-search-ui/resources/ui-and-ux-patterns/in-depth/autocomplete/react/#overview

//const VirtalSearchBox = connectSearchBox(() => null);

const searchClient = algoliasearch('B1G2GM9NG0', 'aadef574be1f9252bb48d4ea09b5cfe5');

class AlgoliaSearch extends Component {
  state = {
    query: '',
  };

  onSuggestionSelected = (_, { suggestion }) => {
    this.setState({
      query: suggestion.name,
    });
    console.log('Setting suggestion.name: ' + suggestion.name);
    this.props.searchValue(suggestion.name);
  };

  onSuggestionCleared = () => {
    this.setState({
      query: '',
    });
  };

  render() {
    const { query } = this.state;

    return (
      <div>
        {/* <h1>React InstantSearch - Results page with autocomplete</h1> */}
        <InstantSearch indexName="demo_ecommerce" searchClient={searchClient}>
          <Configure hitsPerPage={3} />
          <Autocomplete
            onSuggestionSelected={this.onSuggestionSelected}
            onSuggestionCleared={this.onSuggestionCleared}
          />
        </InstantSearch>
      </div>
    );
  }
}

function Hit(props) {
  return (
    <div>
      <Highlight attribute="name" hit={props.hit} />
    </div>
  );
}

Hit.propTypes = {
  hit: PropTypes.object.isRequired,
};

export default AlgoliaSearch;

При автозаполнении. js

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Highlight, connectAutoComplete } from 'react-instantsearch-dom';
import AutoSuggest from 'react-autosuggest';

class AutoComplete extends Component {
  static propTypes = {
    hits: PropTypes.arrayOf(PropTypes.object).isRequired,
    currentRefinement: PropTypes.string.isRequired,
    refine: PropTypes.func.isRequired,
    onSuggestionSelected: PropTypes.func.isRequired,
    onSuggestionCleared: PropTypes.func.isRequired,
  };

  state = {
    value: this.props.currentRefinement,
  };

  onChange = (_, { newValue }) => {
    if (!newValue) {
      this.props.onSuggestionCleared();
    }

    this.setState({
      value: newValue,
    });
  };

  onSuggestionsFetchRequested = ({ value }) => {
    this.props.refine(value);
  };

  onSuggestionsClearRequested = () => {
    this.props.refine();
  };

  getSuggestionValue(hit) {
    return hit.name;
  }

  renderSuggestion(hit) {
    return <Highlight attribute="name" hit={hit} tagName="mark" />;
  }

  render() {
    const { hits, onSuggestionSelected } = this.props;
    const { value } = this.state;

    const inputProps = {
      placeholder: 'Search for a doctor...',
      onChange: this.onChange,
      value,
    };

    return (
      <AutoSuggest
        suggestions={hits}
        onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
        onSuggestionsClearRequested={this.onSuggestionsClearRequested}
        onSuggestionSelected={onSuggestionSelected}
        getSuggestionValue={this.getSuggestionValue}
        renderSuggestion={this.renderSuggestion}
        inputProps={inputProps}
        name="selectedDoctor"
      />
    );
  }
}

export default connectAutoComplete(AutoComplete);
...