diff --git a/src/Field.js b/src/Field.js index baab6f01..46493e85 100644 --- a/src/Field.js +++ b/src/Field.js @@ -55,6 +55,11 @@ const Field = ({ // ignore meta, combine input with any other props return React.createElement(component, { ...field.input, children, ...rest }) } + + if (!name) { + throw new Error('prop name cannot be undefined in component') + } + return renderComponent( { children, component, ...rest }, field, diff --git a/src/Field.test.js b/src/Field.test.js index 888eaf5a..863ad637 100644 --- a/src/Field.test.js +++ b/src/Field.test.js @@ -5,9 +5,9 @@ import { ErrorBoundary, Toggle, wrapWith } from './testUtils' import Form from './ReactFinalForm' import Field from './Field' -const onSubmitMock = values => {} +const onSubmitMock = (values) => {} -const timeout = ms => new Promise(resolve => setTimeout(resolve, ms)) +const timeout = (ms) => new Promise((resolve) => setTimeout(resolve, ms)) async function sleep(ms) { await act(async () => { await timeout(ms) @@ -36,7 +36,7 @@ describe('Field', () => { it('should resubscribe if name changes', () => { const { getByTestId, getByText } = render( - {isCat => ( + {(isCat) => (
{ // This is mainly here for code coverage. 🧐 const { getByText } = render( - {hidden => ( + {(hidden) => ( { {wrapWith(spy, () => ( - v}> + v}> {({ input: { value, ...props } }) => ( { (value ? value.toUpperCase() : '')} + format={(value) => (value ? value.toUpperCase() : '')} data-testid="name" /> @@ -258,7 +258,7 @@ describe('Field', () => { }) it('should only format on blur if formatOnBlur is true', () => { - const format = jest.fn(value => (value ? value.toUpperCase() : '')) + const format = jest.fn((value) => (value ? value.toUpperCase() : '')) const { getByTestId } = render(
{() => ( @@ -286,7 +286,7 @@ describe('Field', () => { }) it('should `formatOnBlur` most updated value', () => { - const format = jest.fn(value => (value ? value.trim() : '')) + const format = jest.fn((value) => (value ? value.trim() : '')) const { getByTestId } = render( {() => ( @@ -296,7 +296,7 @@ describe('Field', () => { { + onBlur={(e) => { input.onChange( e.target.value && e.target.value.toUpperCase() ) @@ -320,7 +320,7 @@ describe('Field', () => { }) it('should not format value at all when formatOnBlur and render prop', () => { - const format = jest.fn(value => (value ? value.toUpperCase() : '')) + const format = jest.fn((value) => (value ? value.toUpperCase() : '')) render( {() => ( @@ -344,7 +344,7 @@ describe('Field', () => { {() => ( - v}> + v}> {wrapWith(spy, ({ input: { value, ...props } }) => ( { }) it('should allow changing field-level validation function', () => { - const simpleValidate = value => (value ? undefined : 'Required') - const complexValidate = value => { + const simpleValidate = (value) => (value ? undefined : 'Required') + const complexValidate = (value) => { if (value) { if (value !== value.toUpperCase()) { return 'SHOULD BE UPPERCASE!' @@ -547,7 +547,7 @@ describe('Field', () => { } const { getByTestId, getByText } = render( - {useComplexValidation => ( + {(useComplexValidation) => ( {({ handleSubmit }) => ( @@ -594,8 +594,8 @@ describe('Field', () => { * form. */ it('should ignore changes field-level validation function', () => { - const createValidator = isRequired => - isRequired ? value => (value ? undefined : 'Required') : undefined + const createValidator = (isRequired) => + isRequired ? (value) => (value ? undefined : 'Required') : undefined const Error = ({ name }) => ( @@ -604,7 +604,7 @@ describe('Field', () => { ) const { getByTestId, getByText } = render( - {isRequired => ( + {(isRequired) => ( {({ handleSubmit }) => ( @@ -640,7 +640,7 @@ describe('Field', () => { it('should not rerender if validateFields is !== every time', () => { // https://github.com/final-form/react-final-form/issues/502 - const required = value => (value ? undefined : 'Required') + const required = (value) => (value ? undefined : 'Required') const spy = jest.fn() const { getByTestId } = render( @@ -1022,7 +1022,7 @@ describe('Field', () => { value && value.toUpperCase()} + format={(value) => value && value.toUpperCase()} formatOnBlur data-testid="name" /> @@ -1091,7 +1091,7 @@ describe('Field', () => { { + validate={async (value) => { await timeout(5) return value === 'erikras' ? 'Username taken' : undefined }} @@ -1136,7 +1136,7 @@ describe('Field', () => { const validate = jest.fn() const { getByText } = render( - {showOtherFields => ( + {(showOtherFields) => ( {({ handleSubmit }) => ( @@ -1168,13 +1168,13 @@ describe('Field', () => { it('submit should not throw when field with enabled `formatOnBlur` changes name `prop`', () => { const onSubmit = jest.fn() - const trim = value => value && value.trim() + const trim = (value) => value && value.trim() const { getByTestId, getByText } = render( {({ handleSubmit }) => ( - {newFieldName => ( + {(newFieldName) => ( { expect(onSubmit).toHaveBeenCalled() expect(onSubmit.mock.calls[0][0]).toEqual({ newName: 'trailing space' }) }) + + it('should throw an error if name prop is undefined', () => { + jest.spyOn(console, 'error').mockImplementation(() => {}) + + const errorSpy = jest.fn() + render( + + + {() => } />} + + + ) + + expect(errorSpy).toHaveBeenCalled() + expect(errorSpy).toHaveBeenCalledTimes(1) + expect(errorSpy.mock.calls[0][0].message).toBe( + 'prop name cannot be undefined in component' + ) + console.error.mockRestore() + }) })