【问题标题】:How to patch values in formik?如何修补formik中的值?
【发布时间】:2020-08-16 14:59:16
【问题描述】:

我在 React 中使用 formik 提交表单,但是,当我想“修补”时,formik 会推送整个对象而不是修改的字段 这是我的代码:

editProfile.js

import React, { useEffect } from 'react';
import { makeStyles, Grid, Typography, TextField, Button } from '@material-ui/core';
import { Formik, Form } from 'formik';
import * as Yup from 'yup';
import { useDispatch, useSelector } from 'react-redux';
import { updateUser } from '../actions';
import { useHistory } from 'react-router-dom';
import NavBar from './navBar';
const useStyles = makeStyles((theme) => ({
    
}));


const Validation = Yup.object().shape({
    firstName: Yup
        .string()
        .min(2, 'Name is too short!')
        .max(15, 'Name is too long!')
        .notRequired(),

    secondName: Yup
        .string()
        .min(2, 'Name is too short!')
        .max(15, 'Name is too long!')
        .notRequired(),

    lastName: Yup
        .string()
        .min(2, 'Name is too short!')
        .max(15, 'Name is too long!')
        .notRequired(),

    password: Yup
        .string()
        .min(6, 'Password too short')
        .max(20, 'Password too long')
        .notRequired(),
    age: Yup
        .number()
        .positive('Age must not be negative')
        .notRequired(),
    bloodGroup: Yup
        .string()
        .max(3, 'Blood group can\'t greater than 3')
        .notRequired(),
    weight: Yup
        .number()
        .positive('Weight must be a positive number')
        .notRequired(),
    bmi: Yup
        .number()
        .positive()
        .notRequired(),
    leftEye: Yup
        .number()
        .max(6)
        .positive()
        .notRequired(),
    rightEye: Yup
        .number()
        .max(6)
        .positive()
        .notRequired(),
    doctorName: Yup
        .string()
        .max(15, 'Name is too long!')
        .notRequired(),
    doctorEmail: Yup
        .string()
        .email()
        .notRequired(),
    doctorPhone: Yup
        .number()
        .notRequired(),
    specialist: Yup
        .string()
        .notRequired(),
    address: Yup
        .string()
        .max(100, 'Too long address')
        .notRequired(),
    lastVisit: Yup
        .date()
        .notRequired(),
    nextVisit: Yup
        .date()
        .notRequired(),

})


const EditProfile = () => {
    const classes = useStyles();
    const dispatch = useDispatch();
    const user = useSelector(state => state.auth.user);
    const isSignedIn = useSelector(state => state.auth.isSignedIn);
    const history = useHistory();
    useEffect(() => {
        if (!isSignedIn) {
            history.push('/')
        }
    }, [isSignedIn, history])
    if (!user) {
        return null;
    } else {
        return (
            <React.Fragment>
                <NavBar />
                <Grid
                    container
                    direction='column'
                    justify='flex-start'
                    alignItems='flex-start'
                    className={classes.gridHome}
                >
                    <Grid item xs={12} className={classes.gridContent}>
                        <Typography className={classes.title}>Medico</Typography>
                    </Grid>
                    <Grid item xs={12} className={classes.gridContent}>
                        <Typography className={classes.signUp}>Welcome {user.user.firstName ? user.user.firstName : null}!</Typography>
                    </Grid>

                    <Formik

                        initialValues={{
                            firstName: '',
                            secondName: '',
                            lastName: '',
                            password: '',
                            age: '',
                            bloodGroup: '',
                            weight: '',
                            leftEye: 1,
                            rightEye: 1,
                            bmi: 1,
                            doctorName: '',
                            doctorPhone: 0,
                            doctorEmail: '',
                            address: '',
                            specialist: '',
                            lastVisit: new Date(),
                            nextVisit: new Date(),
                        }}
                        validationSchema={Validation}
                        onSubmit={(values) => {
                            dispatch(updateUser(values))
                        }}
                    >
                        {({ errors, handleChange, touched }) =>
                            <Form style={{ width: '100%' }}>
                                <Grid container direction='row'>
                                    <Grid item xs={12} className={classes.name}>
                                        <Typography className={classes.signUp}>Name</Typography>
                                    </Grid>
                                    <Grid item md={4} xs={12} className={classes.inputGrid}>
                                        <TextField
                                            className={classes.inputFields}
                                            error={errors.firstName && touched.firstName}
                                            name='firstName'
                                            autoComplete='on'
                                            shrink='true'
                                            variant='standard'
                                            onChange={handleChange}
                                            id='firstName'
                                            label='First Name'
                                            helperText={
                                                errors.firstName && touched.firstName
                                                    ? errors.firstName : null
                                            }
                                        />
                                    </Grid>
                                    <Grid item md={4} xs={12} className={classes.inputGrid}>
                                        <TextField
                                            className={classes.inputFields}
                                            error={errors.secondName && touched.secondName}
                                            name='secondName'
                                            autoComplete='on'
                                            variant='standard'
                                            onChange={handleChange}
                                            id='secondName'
                                            label='Middle Name'
                                            helperText={
                                                errors.secondName && touched.secondName
                                                    ? errors.secondName : null
                                            }
                                        />
                                    </Grid>
                                    <Grid item md={4} xs={12} className={classes.inputGrid}>
                                        <TextField
                                            className={classes.inputFields}
                                            error={errors.lastName && touched.lastName}
                                            name='lastName'
                                            autoComplete='on'
                                            variant='standard'
                                            onChange={handleChange}
                                            id='lastName'
                                            label='Last Name'
                                            helperText={
                                                errors.lastName && touched.lastName
                                                    ? errors.lastName : null
                                            }
                                        />
                                    </Grid>

                                    <Grid item xs={12} className={classes.name}>
                                        <Typography className={classes.signUp}>Password</Typography>
                                    </Grid>
                                    <Grid item md={6} xs={12} className={classes.inputGrid}>
                                        <TextField
                                            className={classes.inputFields}
                                            error={errors.password && touched.password}
                                            name='password'
                                            type='password'
                                            variant='standard'
                                            onChange={handleChange}
                                            id='password'
                                            label='Password'
                                            helperText={
                                                errors.password && touched.password
                                                    ? errors.password : null
                                            }
                                        />
                                    </Grid>
                                    <Grid item xs={12} className={classes.name}>
                                        <Typography className={classes.signUp}>Personal Information</Typography>
                                    </Grid>
                                    <Grid item md={2} xs={6} className={classes.inputGrid} >
                                        <TextField
                                            className={classes.inputFields}
                                            error={errors.age && touched.age}
                                            name='age'
                                            variant='standard'
                                            onChange={handleChange}
                                            id='age'
                                            label='Age'
                                            helperText={
                                                errors.age && touched.age
                                                    ? errors.age : null
                                            }
                                        />
                                    </Grid>
                                    <Grid item md={2} xs={6} className={classes.inputGrid} >
                                        <TextField
                                            className={classes.inputFields}
                                            error={errors.bloodGroup && touched.bloodGroup}
                                            name='bloodGroup'
                                            variant='standard'
                                            onChange={handleChange}
                                            id='bloodGroup'
                                            label='Blood Group'
                                            helperText={
                                                errors.bloodGroup && touched.bloodGroup
                                                    ? errors.bloodGroup : null
                                            }
                                        />
                                    </Grid>
                                    <Grid item md={2} xs={6} className={classes.inputGrid} >
                                        <TextField
                                            className={classes.inputFields}
                                            error={errors.weight && touched.weight}
                                            name='weight'
                                            variant='standard'
                                            onChange={handleChange}
                                            id='weight'
                                            label='Weight(in Kg)'
                                            helperText={
                                                errors.weight && touched.weight
                                                    ? errors.weight : null
                                            }
                                        />
                                    </Grid>
                                    <Grid item md={2} xs={6} className={classes.inputGrid} >
                                        <TextField
                                            className={classes.inputFields}
                                            error={errors.bmi && touched.bmi}
                                            name='bmi'
                                            variant='standard'
                                            onChange={handleChange}
                                            id='bmi'
                                            label='BMI'
                                            helperText={
                                                errors.bmi && touched.bmi
                                                    ? errors.bmi : null
                                            }
                                        />
                                    </Grid>
                                    <Grid item md={2} xs={6} className={classes.inputGrid} >
                                        <TextField
                                            className={classes.inputFields}
                                            error={errors.leftEye && touched.leftEye}
                                            name='leftEye'
                                            variant='standard'
                                            onChange={handleChange}
                                            id='leftEye'
                                            label='Left Eye'
                                            helperText={
                                                errors.leftEye && touched.leftEye
                                                    ? errors.leftEye : null
                                            }
                                        />
                                    </Grid>
                                    <Grid item md={2} xs={6} className={classes.inputGrid} >
                                        <TextField
                                            className={classes.inputFields}
                                            error={errors.rightEye && touched.rightEye}
                                            name='rightEye'
                                            variant='standard'
                                            onChange={handleChange}
                                            id='rightEye'
                                            label='Right Eye'
                                            helperText={
                                                errors.rightEye && touched.rightEye
                                                    ? errors.rightEye : null
                                            }
                                        />
                                    </Grid>
                                    <Grid item xs={6} container justify='center' alignItems='center' className={classes.loginGrid}>
                                        <Button
                                            className={classes.button}
                                            type='submit'
                                            variant='contained'
                                        >Submit</Button>
                                    </Grid>
                                </Grid>
                            </Form>
                        }
                    </Formik>
                </Grid>
            </React.Fragment >
        );
    }


}

export default EditProfile;

假设我只想为“PATCH”推送“secondName”,而不是 formik 提交“initialValues”中提到的所有字段。如何控制该 formik 仅提交已更改的字段。 PS:我删除了一些字段以缩短 sn-p。

【问题讨论】:

    标签: reactjs formik


    【解决方案1】:

    我认为它非常简单...您只需将 initialValues 与 onSubmit 处理程序中的值进行比较。希望这个sn-p足够看懂

    
    const getModifiedValues = (values, initialValues) => {
      let modifiedValues = {};
    
      if (values) {
        Object.entries(values).forEach((entry) => {
          let key = entry[0];
          let value = entry[1];
    
          if (value !== initialValues[key]) {
            modifiedValues[key] = value;
          }
        });
      }
    
      return modifiedValues;
    };
    
    const initialValues = {
        firstName: '',
        secondName: '',
        lastName: '',
        password: '',
        age: '',
        bloodGroup: '',
        weight: '',
        leftEye: 1,
        rightEye: 1,
        bmi: 1,
        doctorName: '',
        doctorPhone: 0,
        doctorEmail: '',
        address: '',
        specialist: '',
        lastVisit: new Date(),
        nextVisit: new Date(),
    };
    
    <Formik
        initialValues={initialValues}
        validationSchema={Validation}
        onSubmit={(values) => {
            // this function should return the only modified values.
            const modifiedValues = getModifiedValues(values, initialValues); 
            dispatch(updateUser(modifiedValues))
        }}
    >
    ...
    </Formik>
    

    我找到了一个链接,它已经被回答了。

    Only send values that have changed in formik onSubmit

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-12
      • 2021-03-08
      • 2021-03-25
      • 2022-07-09
      • 1970-01-01
      • 1970-01-01
      • 2021-02-10
      相关资源
      最近更新 更多