vendredi 18 septembre 2020

useFormState must be used inside of a but useFormState is inside of Form

i try to make tests for React-redux project, i use enzyme and jest. When i try to mount component ForgotPasswordForm, then i get error useFormState must be used inside of a Form, but this component is tag Form with content inside. I noticed that error makes child-component SubmitErrorAlerts.jsx, but can't understand what's a problem.

Can you help me with solve of problem with useForm inside of Form in test?

P.S. useForm is taken from react-final-form.

CompanyForgotPasswordForm.test.jsx

/* eslint-disable no-undef */
/* eslint-disable no-unused-vars */
import React from 'react'
import { shallow, mount } from 'enzyme'
import ForgotPasswordForm from './CompanyForgotPasswordForm'

// eslint-disable-next-line no-undef

describe('CompanyForgotPasswordForm component tests', () => {
  const fakeProps = {
    handleSubmit: jest.fn(x => x),
    submitSucceeded: false,
    submitting: false,
  }
  it('CompanySignInForm ', () => {
    const wrapper = mount(<ForgotPasswordForm {...fakeProps} />)
  })
})

CompanyForgotPasswordForm.jsx

import React from 'react'
import { bool, func } from 'prop-types'
import { Alert, Button, Form } from 'reactstrap'
import { useUIDSeed } from 'react-uid'
import { validateEmail, validateRequired } from '../../lib/ff'
import { FFormGroup, SubmitErrorAlerts } from '../ff'

ForgotPasswordForm.propTypes = {
  handleSubmit: func.isRequired,
  submitSucceeded: bool.isRequired,
  submitting: bool.isRequired,
}

function ForgotPasswordForm({ handleSubmit, submitSucceeded, submitting }) {
  const seed = useUIDSeed()

  return (
    <Form onSubmit={handleSubmit}>
      {submitSucceeded ? (
        <Alert color="success">
          Follow the instructions in the email we have now sent you to complete
          your password reset.
        </Alert>
      ) : (
        <>
          <FFormGroup
            label="Email Address"
            name="email"
            type="email"
            seed={seed}
            validators={[validateRequired(), validateEmail()]}
            formText="Enter the email associated with your account then you will be
              emailed a link to reset your password."
            autoComplete="username email"
            inputMode="email"
          />
          <SubmitErrorAlerts />
          <Button
            block
            color="secondary"
            className="uaTrack-submit-forgot-password"
            disabled={submitting || submitSucceeded}
            type="submit"
          >
            {submitting || submitSucceeded
              ? 'Requesting Reset...'
              : 'Request Reset'}
          </Button>
        </>
      )}
    </Form>
  )
}

export default ForgotPasswordForm

SubmitErrorAlerts.jsx

import React from 'react'
import { string } from 'prop-types'
import { map, isString } from 'lodash'
import { Alert } from 'reactstrap'
import { useFormState } from 'react-final-form'
import { useUIDSeed } from 'react-uid'

/**
 * Produces error alerts from Final-Form submitError form state
 *
 * @see https://github.com/final-form/final-form#submiterror-any-1
 * @see https://github.com/final-form/react-final-form#submission-errors
 */

SubmitErrorAlerts.propTypes = {
  className: string,
}

SubmitErrorAlerts.defaultProps = {
  className: undefined,
}

function SubmitErrorAlerts({ className }) {
  const seed = useUIDSeed()
  const { submitError, submitting } = useFormState({
    subscription: { submitError: true, submitting: true },
  })
  if (!submitError || submitting) return null

  return isString(submitError) ? (
    // single error alert
    <Alert className={className} color="danger">
      {submitError}
    </Alert>
  ) : (
    // multiple error alerts
    map(submitError, errorMsg => (
      <Alert
        className={className}
        key={`SubmitError-${seed(errorMsg)}`}
        color="danger"
      >
        {errorMsg}
      </Alert>
    ))
  )
}

export default SubmitErrorAlerts

Code of error:

CompanyForgotPasswordForm component tests › CompanySignInForm 

    useFormState must be used inside of a <Form> component

      23 | function SubmitErrorAlerts({ className }) {
      24 |   const seed = useUIDSeed()
    > 25 |   const { submitError, submitting } = useFormState({
         |                                       ^
      26 |     subscription: { submitError: true, submitting: true },
      27 |   })
      28 |   if (!submitError || submitting) return null

      at useForm (node_modules/react-final-form/dist/react-final-form.cjs.js:299:11)
      at useFormState (node_modules/react-final-form/dist/react-final-form.cjs.js:311:14)
      at SubmitErrorAlerts (components/ff/SubmitErrorAlerts.jsx:25:39)
....

Aucun commentaire:

Enregistrer un commentaire