' fieldArray'不能用作JSX组件

发布于 2025-01-30 08:00:37 字数 6638 浏览 1 评论 0原文

在我的下一个项目中,我使用了formik组件。但是它显示了类型错误,即“'FieldArray'不能用作JSX组件。”如何修复它?

错误是

 'FieldArray' cannot be used as a JSX component.
  Its element type 'ReactElement<any, any> | Component<FieldArrayConfig, any, any> | null' is not a valid JSX element.
    Type 'Component<FieldArrayConfig, any, any>' is not assignable to type 'Element | ElementClass | null'.
      Type 'Component<FieldArrayConfig, any, any>' is not assignable to type 'ElementClass'.
        The types returned by 'render()' are incompatible between these types.
          Type 'React.ReactNode' is not assignable to type 'import("/home/shoyon/WorkPlace/Practice/EmailSystem/view/node_modules/@types/react-transition-group/node_modules/@types/react/index").ReactNode'.
            Type '{}' is not assignable to type 'ReactNode'.ts(2786)

我的代码是:

import React, { useEffect, useState } from 'react'
import AttachmentForm from '@components/Forms/AttachmentForm'
import { ProjectActionType } from '@enums/enums'
import { Button, Divider, Grid, Link, Typography } from '@mui/material'
import { Notify } from '@utils/common'
import { FormikTextField, MultiValueInput } from '@utils/FormElements'
import { FieldArray, Form, Formik, FormikProps } from 'formik'
import * as Yup from 'yup'
import { useRouter } from 'next/router'
import { createTemplate, getTemplateById } from 'requests/templates'

interface pageProps {
    type: ProjectActionType
}

interface AttachmentValues {
    attachmentName: any;
    attachmentData: string;
}

interface FieldValues {
    projectId: number | null;
    title: string;
    cc?: string;
    bcc?: string
    templateName?: string;
    templateData?: string
    attachment?: AttachmentValues[] | [] | null;
}

const SingleTemplate = ({ type }: pageProps) => {
    const router = useRouter();
    
    const [data, setData] = useState<FieldValues>({
        projectId: null,
        title: '',
        templateName:'',
        templateData: '',
        cc: '',
        bcc: '',
        attachment: []
    });

    const validationSchema = Yup.object().shape({
        projectId: Yup.number().required('Field required'),
        title: Yup.string().required('Field required'),
        templateName: type === ProjectActionType.ADD ? Yup.mixed().required('File is required') : Yup.mixed(),
        templateData: Yup.string().required('Field required'),
        cc: Yup.string(),
        bcc: Yup.string(),
        attachment: Yup.array().of(
            Yup.object().shape({
                attachmentName: Yup.mixed().required('File is required'),
                attachmentData: type === ProjectActionType.ADD ? Yup.mixed().required('Data is required') : Yup.mixed(),
            })
        )
    });

    const getTemplateData = async (id: number)=> {
        let res = await getTemplateById(id);
        if (res?.statusCode === 200) setData({
            ...data,
            title: res.data.title,
            templateName: res.data.templateName,
            templateData: JSON.stringify(res.data.templateData),
            cc: res.data.cc,
            bcc: res.data.bcc,
            attachment: res.data.attachment
        });
        else Notify(res?.message, 'error');
    }

    const handleSubmit = async (values: FieldValues, setSubmitting: any) => {
        let res = await createTemplate(values);
        if (res?.statusCode === 201) Notify('Template added', 'success');
        else Notify(res?.message, 'error');
        setSubmitting(false);
    }

    useEffect(()=>{
        if(router.query.id) {
            const id = parseInt(router.query.id as string, 10);
            setData({...data, projectId: id});
            if(type === ProjectActionType.EDIT) getTemplateData(id);
        }
    // eslint-disable-next-line react-hooks/exhaustive-deps
    },[router])
    

    return (
        <React.Fragment>
            <Typography variant='h5' mb={4}>Email Settings</Typography>
            <Formik 
                enableReinitialize={true}
                initialValues={data}
                validationSchema={validationSchema} 
                onSubmit={(values, { setSubmitting }) => {
                    handleSubmit(values, setSubmitting);
                }}
            >
                {(props: FormikProps<any>) => {
                    const { values, touched, errors, handleBlur, handleChange, isSubmitting } = props
                    return (
                        <Form noValidate autoComplete="off">
                            ...

                            <Divider className='mb-6' />
                            <FieldArray name="attachment"
                                render={arrayHelpers => (
                                    <React.Fragment>
                                        {values.attachment && values.attachment.map((key: any, i: number) => (
                                            <AttachmentForm key={i}
                                                index={i}
                                                id={key}
                                                onDelete={() => arrayHelpers.remove(i)}
                                                values={values}
                                                touched={touched}
                                                errors={errors}
                                                handleBlur={handleBlur}
                                                handleChange={handleChange}
                                            />
                                        ))}
                                        <div className="flex">
                                            <Button variant="contained" color='info' className='mr-3' type='submit' disabled={isSubmitting}>Save</Button>
                                            <Button variant="contained" onClick={() => arrayHelpers.push({ attachmentName: '', attachmentData: '' })}>
                                                Add Attachment
                                            </Button>
                                        </div>
                                    </React.Fragment>
                                )}
                            />
                        </Form>
                    )
                }}
            </Formik>
        </React.Fragment>
    )
}

export default SingleTemplate

In my next.js project, I have used Formik component. But it shows a type error, which is "'FieldArray' cannot be used as a JSX component. " How can I fix it?

The Error is

 'FieldArray' cannot be used as a JSX component.
  Its element type 'ReactElement<any, any> | Component<FieldArrayConfig, any, any> | null' is not a valid JSX element.
    Type 'Component<FieldArrayConfig, any, any>' is not assignable to type 'Element | ElementClass | null'.
      Type 'Component<FieldArrayConfig, any, any>' is not assignable to type 'ElementClass'.
        The types returned by 'render()' are incompatible between these types.
          Type 'React.ReactNode' is not assignable to type 'import("/home/shoyon/WorkPlace/Practice/EmailSystem/view/node_modules/@types/react-transition-group/node_modules/@types/react/index").ReactNode'.
            Type '{}' is not assignable to type 'ReactNode'.ts(2786)

My code is:

import React, { useEffect, useState } from 'react'
import AttachmentForm from '@components/Forms/AttachmentForm'
import { ProjectActionType } from '@enums/enums'
import { Button, Divider, Grid, Link, Typography } from '@mui/material'
import { Notify } from '@utils/common'
import { FormikTextField, MultiValueInput } from '@utils/FormElements'
import { FieldArray, Form, Formik, FormikProps } from 'formik'
import * as Yup from 'yup'
import { useRouter } from 'next/router'
import { createTemplate, getTemplateById } from 'requests/templates'

interface pageProps {
    type: ProjectActionType
}

interface AttachmentValues {
    attachmentName: any;
    attachmentData: string;
}

interface FieldValues {
    projectId: number | null;
    title: string;
    cc?: string;
    bcc?: string
    templateName?: string;
    templateData?: string
    attachment?: AttachmentValues[] | [] | null;
}

const SingleTemplate = ({ type }: pageProps) => {
    const router = useRouter();
    
    const [data, setData] = useState<FieldValues>({
        projectId: null,
        title: '',
        templateName:'',
        templateData: '',
        cc: '',
        bcc: '',
        attachment: []
    });

    const validationSchema = Yup.object().shape({
        projectId: Yup.number().required('Field required'),
        title: Yup.string().required('Field required'),
        templateName: type === ProjectActionType.ADD ? Yup.mixed().required('File is required') : Yup.mixed(),
        templateData: Yup.string().required('Field required'),
        cc: Yup.string(),
        bcc: Yup.string(),
        attachment: Yup.array().of(
            Yup.object().shape({
                attachmentName: Yup.mixed().required('File is required'),
                attachmentData: type === ProjectActionType.ADD ? Yup.mixed().required('Data is required') : Yup.mixed(),
            })
        )
    });

    const getTemplateData = async (id: number)=> {
        let res = await getTemplateById(id);
        if (res?.statusCode === 200) setData({
            ...data,
            title: res.data.title,
            templateName: res.data.templateName,
            templateData: JSON.stringify(res.data.templateData),
            cc: res.data.cc,
            bcc: res.data.bcc,
            attachment: res.data.attachment
        });
        else Notify(res?.message, 'error');
    }

    const handleSubmit = async (values: FieldValues, setSubmitting: any) => {
        let res = await createTemplate(values);
        if (res?.statusCode === 201) Notify('Template added', 'success');
        else Notify(res?.message, 'error');
        setSubmitting(false);
    }

    useEffect(()=>{
        if(router.query.id) {
            const id = parseInt(router.query.id as string, 10);
            setData({...data, projectId: id});
            if(type === ProjectActionType.EDIT) getTemplateData(id);
        }
    // eslint-disable-next-line react-hooks/exhaustive-deps
    },[router])
    

    return (
        <React.Fragment>
            <Typography variant='h5' mb={4}>Email Settings</Typography>
            <Formik 
                enableReinitialize={true}
                initialValues={data}
                validationSchema={validationSchema} 
                onSubmit={(values, { setSubmitting }) => {
                    handleSubmit(values, setSubmitting);
                }}
            >
                {(props: FormikProps<any>) => {
                    const { values, touched, errors, handleBlur, handleChange, isSubmitting } = props
                    return (
                        <Form noValidate autoComplete="off">
                            ...

                            <Divider className='mb-6' />
                            <FieldArray name="attachment"
                                render={arrayHelpers => (
                                    <React.Fragment>
                                        {values.attachment && values.attachment.map((key: any, i: number) => (
                                            <AttachmentForm key={i}
                                                index={i}
                                                id={key}
                                                onDelete={() => arrayHelpers.remove(i)}
                                                values={values}
                                                touched={touched}
                                                errors={errors}
                                                handleBlur={handleBlur}
                                                handleChange={handleChange}
                                            />
                                        ))}
                                        <div className="flex">
                                            <Button variant="contained" color='info' className='mr-3' type='submit' disabled={isSubmitting}>Save</Button>
                                            <Button variant="contained" onClick={() => arrayHelpers.push({ attachmentName: '', attachmentData: '' })}>
                                                Add Attachment
                                            </Button>
                                        </div>
                                    </React.Fragment>
                                )}
                            />
                        </Form>
                    )
                }}
            </Formik>
        </React.Fragment>
    )
}

export default SingleTemplate

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

遗心遗梦遗幸福 2025-02-06 08:00:37

我使用formikyouteral-uitypescript上遇到了相同的问题。

对我来说,这是@type/react-is版本和@types/react-transition-transition-group内部使用@types/react的主要版本的问题

有些依赖关系是冲突的,使用了不同版本的React,您应该检查并尝试更新/降级它们,以便没有兼容性问题。

在我的情况下,我通过将以下内容添加到package.json

"overrides": {
  "react-is": "^17.0.0",
  "@types/react-is": "^17.0.0",
  "@types/react": "^17.0.0"
}

需要npm&gt; = 8基于此帖子

I had the same problem using formik and material-ui on typescript.

For me it was a problem with @types/react-is version and @types/react-transition-group internally using later major versions of @types/react.

Some dependencies were conflicting and using different version of react, you should check and try to update/downgrade them so there are no compatibility issues.

In my case I solved it by adding the following to package.json:

"overrides": {
  "react-is": "^17.0.0",
  "@types/react-is": "^17.0.0",
  "@types/react": "^17.0.0"
}

Requires npm >= 8 based on this post.

往事随风而去 2025-02-06 08:00:37

我没有解决方案,然后返回手动方法。

{Attachments.length > 0 && Attachments.map((attachment, i) => 
    <AttachmentForm key={i}
        index={i}
        onDelete={(i: number) => {
            removeAttachment(i);
            let arr = [...values.attachment]
            arr.splice(i, 1);
            values.attachment = arr;
        }}
        values={values}
        touched={touched}
        errors={errors}
        handleBlur={handleBlur}
        handleChange={handleChange}
    />
)}

I got no solution and returned back to manual method.

{Attachments.length > 0 && Attachments.map((attachment, i) => 
    <AttachmentForm key={i}
        index={i}
        onDelete={(i: number) => {
            removeAttachment(i);
            let arr = [...values.attachment]
            arr.splice(i, 1);
            values.attachment = arr;
        }}
        values={values}
        touched={touched}
        errors={errors}
        handleBlur={handleBlur}
        handleChange={handleChange}
    />
)}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文