使用formik的REST API PATCH请求

问题描述 投票:0回答:1

我在React中使用formik进行表单提交,但是,当我想 "PATCH "一些东西时,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;

假设我只是想推送'secondName'为'PATCH',而不是formik提交所有的字段,在'initialValues'中提到的.如何控制formik只提交该字段被改变.PS:我已经删除了一些字段,以缩短片段。

reactjs formik
1个回答
1
投票

我认为这很简单...你只需要比较初始值和onSubmit处理程序中的值。我希望这段代码足以让你理解。


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>

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

只发送在formik onSubmit中改变的值。

© www.soinside.com 2019 - 2024. All rights reserved.