可以将一系列数据插入formik状态。仅设置一个元素

发布于 2025-01-26 14:25:15 字数 5133 浏览 2 评论 0 原文

我尝试将一系列文件添加到formik状态,

formik状态中的“文件”属性中:

initialValues={{
                    firstName: '',
                    lastName: '',
                    email: '',
                    phoneNumber: '',
                    files: [],
                }}

但是,无论我选择多少个文件,始终设置了数组中唯一的一个元素。它不断与下一个重新录制!

此处(src/components/dragandDrop/draganddrop.js)我在ondrop函数中应用setFieldValue,因此每次迭代在每个迭代中都添加了每个下一个文件添加到formik state中,但不是。只有单个文件!?

export const DragAndDrop = ({ name, setFieldValue = f => f, currentFiles }) => {
    const styles = useStyles()

    const onDrop = useCallback(
        acceptedFiles => {
            acceptedFiles.forEach(file => {
                setFieldValue(name, [...currentFiles, file])
            })
        },
        [name, setFieldValue, currentFiles]
    )
    const { acceptedFiles, getRootProps, getInputProps } = useDropzone({ onDrop })

    return (
        <>
            <div className={styles.fullBlock}>
                <Paper {...getRootProps({ className: 'dropzone' })} className={styles.root}>
                    <input {...getInputProps()} name={name} />
                    <CloudUploadIcon className={styles.icon} />
                    <Typography
                        variant="subtitle1"
                        gutterBottom
                        component="p"
                        className={styles.text}
                    >
                        Drag and drop some files here, or click to select files
                    </Typography>
                </Paper>
            </div>

            <aside className={styles.fullBlock}>
                <List sx={{ width: '100%', maxWidth: '100%' }} className={styles.fullBlock}>
                    {acceptedFiles.map((file, i) => (
                        <ListItem key={i}>
                            <ListItemAvatar>
                                <InsertDriveFileIcon className={styles.iconFile} />
                            </ListItemAvatar>
                            <ListItemText primary={file.path} secondary={file.size} />
                        </ListItem>
                    ))}
                </List>
            </aside>
        </>
    )
}

在树和最后一个的组件

export const Step3 = ({ context }) => {
    const { setFieldValue, values } = context
    console.log(values)
    return (
        <>
            <Title text={'Step 3'} iconRender={<AccountCircleRoundedIcon />} />
            <DragAndDrop name={'files'} setFieldValue={setFieldValue} currentFiles={values.files} />
            <MyButton>Next</MyButton>
        </>
    )
}

,更高。

export const App = () => {
    const [haveNumber, setHaveNumber] = useState(false)
    return (
        <>
            <Formik
                initialValues={{
                    firstName: '',
                    lastName: '',
                    email: '',
                    phoneNumber: '',
                    files: [],
                }}
                validationSchema={Yup.object({
                    firstName: Yup.string()
                        .max(15, 'Have to be 15 characters or less')
                        .required('Required'),
                    lastName: Yup.string()
                        .max(20, 'Have to be 20 or less characters')
                        .required('Required'),
                    email: Yup.string().required('Required.'),
                    phoneNumber: haveNumber
                        ? Yup.string().phone('UA', false, 'Phone number is invalid')
                        : Yup.string(),
                })}
                onSubmit={(values, { setSubmitting }) => {
                    setTimeout(() => {
                        alert(JSON.stringify(values, null, 2))
                        setSubmitting(false)
                    }, 400)
                }}
            >
                {context => (
                    <Form>
                        <MainContainer>
                            {/*<Step1 />*/}
                            {/*<Step2 context={context} setHaveNumber={setHaveNumber} />*/}

                            <Step3 context={context} />

                            {/*<input type="submit" />*/}
                            {/*<input type="file" multiple onInput={() => console.log('file added')} />*/}
                        </MainContainer>
                    </Form>
                )}
            </Formik>
        </>
    )
}

github:

怎么了?如何解决?

I try to add an array of files into "files" property in Formik state,

Formik state:

initialValues={{
                    firstName: '',
                    lastName: '',
                    email: '',
                    phoneNumber: '',
                    files: [],
                }}

but always the only one element of the array is set no matter how many files I choose. It is constantly re-recorded with the next one!
enter image description here

Here (src/components/DragAndDrop/DragAndDrop.js) I apply setFieldValue in onDrop function, thus with each iteration each next file is added to Formik state, but it is not. Single file only!?

export const DragAndDrop = ({ name, setFieldValue = f => f, currentFiles }) => {
    const styles = useStyles()

    const onDrop = useCallback(
        acceptedFiles => {
            acceptedFiles.forEach(file => {
                setFieldValue(name, [...currentFiles, file])
            })
        },
        [name, setFieldValue, currentFiles]
    )
    const { acceptedFiles, getRootProps, getInputProps } = useDropzone({ onDrop })

    return (
        <>
            <div className={styles.fullBlock}>
                <Paper {...getRootProps({ className: 'dropzone' })} className={styles.root}>
                    <input {...getInputProps()} name={name} />
                    <CloudUploadIcon className={styles.icon} />
                    <Typography
                        variant="subtitle1"
                        gutterBottom
                        component="p"
                        className={styles.text}
                    >
                        Drag and drop some files here, or click to select files
                    </Typography>
                </Paper>
            </div>

            <aside className={styles.fullBlock}>
                <List sx={{ width: '100%', maxWidth: '100%' }} className={styles.fullBlock}>
                    {acceptedFiles.map((file, i) => (
                        <ListItem key={i}>
                            <ListItemAvatar>
                                <InsertDriveFileIcon className={styles.iconFile} />
                            </ListItemAvatar>
                            <ListItemText primary={file.path} secondary={file.size} />
                        </ListItem>
                    ))}
                </List>
            </aside>
        </>
    )
}

The component which is upper in the tree

export const Step3 = ({ context }) => {
    const { setFieldValue, values } = context
    console.log(values)
    return (
        <>
            <Title text={'Step 3'} iconRender={<AccountCircleRoundedIcon />} />
            <DragAndDrop name={'files'} setFieldValue={setFieldValue} currentFiles={values.files} />
            <MyButton>Next</MyButton>
        </>
    )
}

and the last one, which is more upper.

export const App = () => {
    const [haveNumber, setHaveNumber] = useState(false)
    return (
        <>
            <Formik
                initialValues={{
                    firstName: '',
                    lastName: '',
                    email: '',
                    phoneNumber: '',
                    files: [],
                }}
                validationSchema={Yup.object({
                    firstName: Yup.string()
                        .max(15, 'Have to be 15 characters or less')
                        .required('Required'),
                    lastName: Yup.string()
                        .max(20, 'Have to be 20 or less characters')
                        .required('Required'),
                    email: Yup.string().required('Required.'),
                    phoneNumber: haveNumber
                        ? Yup.string().phone('UA', false, 'Phone number is invalid')
                        : Yup.string(),
                })}
                onSubmit={(values, { setSubmitting }) => {
                    setTimeout(() => {
                        alert(JSON.stringify(values, null, 2))
                        setSubmitting(false)
                    }, 400)
                }}
            >
                {context => (
                    <Form>
                        <MainContainer>
                            {/*<Step1 />*/}
                            {/*<Step2 context={context} setHaveNumber={setHaveNumber} />*/}

                            <Step3 context={context} />

                            {/*<input type="submit" />*/}
                            {/*<input type="file" multiple onInput={() => console.log('file added')} />*/}
                        </MainContainer>
                    </Form>
                )}
            </Formik>
        </>
    )
}

github:https://github.com/AlexKor-5/FormChallenge/tree/ed022501ecd741eb198ab56a693878522f48108a

What is the matter? How to tackle it?

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

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

发布评论

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

评论(1

街道布景 2025-02-02 14:25:15

您已经尝试过:

const currentFilesCopy = currentFiles.slice(0); // to get a copy of the original array

currentFilesCopy.push(fileThatJustGotUploaded);

setFieldValue(files, currentFilesCopy);

Did you already tried:

const currentFilesCopy = currentFiles.slice(0); // to get a copy of the original array

currentFilesCopy.push(fileThatJustGotUploaded);

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