''FieldArray' cannot be used as a JSX component

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


Solution 1:[1]

The render method on FieldArray needs to return a single root element. By using React.Fragment, multiple elements are being returned. Changing React.Fragment to a div should resolve the error.

Solution 2:[2]

you can do this in powerquery using either of these options from data ... get data ... from other sources .... blank query and then home ... advanced editor...

To read and combine all XLS files in a directory

//read all files in specified directory you fill in here
let Source = Folder.Files("C:\directory\subdirectory"),
//filter only filetype xlsx
#"Filtered Rows" = Table.SelectRows(Source, each ([Extension] = ".xlsx")),
#"Removed Other Columns" = Table.SelectColumns(#"Filtered Rows",{"Name", "Content"}),
#"Added Custom" = Table.AddColumn(#"Removed Other Columns", "GetFileData", each Excel.Workbook([Content],true)),
#"Expanded GetFileData" = Table.ExpandTableColumn(#"Added Custom", "GetFileData", {"Data", "Hidden", "Item", "Kind", "Name"}, {"Data", "Hidden", "Item", "Kind", "Sheet"}),
#"Removed Columns" = Table.RemoveColumns(#"Expanded GetFileData",{"Content", "Hidden", "Item", "Kind"}),
List = List.Union(List.Transform(#"Removed Columns"[Data], each Table.ColumnNames(_))),
#"Expanded Data" = Table.ExpandTableColumn(#"Removed Columns", "Data", List,List)
in  #"Expanded Data"

to read and combine all text files (you specify extension) in directory

let Source = Folder.Files("C:\directory\subdirectory"),
//filter only filetype txt
#"Filtered Rows" = Table.SelectRows(Source, each ([Extension] = ".txt")),
#"Added Custom1" = Table.AddColumn(#"Filtered Rows", "Custom", each Table.AddIndexColumn(Csv.Document(File.Contents([Folder Path]&"\"&[Name]),[Delimiter=",", Encoding=1252, QuoteStyle=QuoteStyle.None]),"Index")),
#"Expanded Custom" = Table.ExpandTableColumn(#"Added Custom1", "Custom", {"Column1", "Index"}, {"Column1", "Index"}),
#"Removed Other Columns" = Table.SelectColumns(#"Expanded Custom",{"Column1", "Index", "Name"}),
#"Pivoted Column" = Table.Pivot(#"Removed Other Columns", List.Distinct(#"Removed Other Columns"[Name]), "Name", "Column1"),
#"Removed Columns" = Table.RemoveColumns(#"Pivoted Column",{"Index"})
in #"Removed Columns"

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Stafford Rose
Solution 2 horseyride