如何通过ApolloClient的突变提交Formik表单?

时间:2019-02-25 13:57:15

标签: reactjs gatsby antd apollo-client formik

我已经使用antd创建了一个示例Formik表单。现在我用POST_MUTATION添加了变异。如何通过formik提交表单值。在这里,我以form的形式调用handleSubmit。但是它没有被调用吗?

 import React from 'react'
import { Formik, Field, Form } from 'formik';
import * as AntD from "antd";
import TextField from "./shared/TextField"
import { Mutation, graphql } from 'react-apollo'
import gql from 'graphql-tag'
import data from './shared/data'

const POST_MUTATION = gql`
  mutation PostMutation($username: String!, $email: String!, $password: String!){
    post(username: $username, email: $email, password: $password) {

      username
      email
      password
    }
  }
`


class FormikApollo extends React.Component {
  state = {
      username: '',
      email: '',
      password: '',
      data: {}
  }

  handleChange= (e) => {
        this.setState({
            [e.target.name] : e.target.value,
            data
        })
  }

  handleSubmit = () => {
   alert("called")
  }

然后我以这种方式添加formik表单。现在我想提交未提交的表单值。如何在formik中提交表单值?

form = props => {
            const { username, email, password  } = this.state;
            return (
                <div align="center">
                    <h3 align="center">Registration Form</h3>
                    <Mutation mutation={POST_MUTATION} variables={{ username, email, password }}>
                    { postMutation  => (
                    <Form onSubmit={(formikValues) => postMutation({ variables: formikValues })}>
                        <Row gutter={4}>
                            <Col span={12} push={5}>
                                <Field
                                    name="username"
                                    label="Name"
                                    placeholder="Enter a Name"
                                    component={TextField}
                                    formitemlayout={formItemLayout} 
                                    value={this.state.username}
                                    onChange={this.handleChange}
                                    />

                                <Field
                                    name="email"
                                    label="Email"
                                    placeholder="Enter an Email"
                                    component={TextField}
                                    formitemlayout={formItemLayout} 
                                    value={this.state.email}
                                    onChange={this.handleChange}
                                    />

                                <Field
                                    name="password"
                                    label="Password"
                                    type="password"
                                    placeholder="Enter a Password"
                                    component={TextField}
                                    formitemlayout={formItemLayout} 
                                    value={this.state.password}
                                    onChange={this.handleChange}
                                  />


                                 <Button type="submit" onClick={JSON.stringify(postMutation)}>Submit</Button>


                            </Col>
                        </Row>
                    </Form>
                    )}

                    </Mutation>
                </div>
            )
        }


        render() {

            return (
                <div align="center">
                    <Formik
                        initialValues = {{
                          username: '',
                          email:'',
                          password:''
                        }}
                        render={this.form}
                    />

                </div>
            )
        }

    }

    export default FormikApollo

3 个答案:

答案 0 :(得分:1)

您的方法是正确的。最好将整个组件包装成突变并将其用作渲染道具。 这是一个简单的寄存器组件。如果您发现某些语法难以理解,那么我正在使用打字稿。

使用ant-design和graphql(Typescript)的工作示例:https://github.com/benawad/graphql-typescript-stripe-example

Youtube系列:https://www.youtube.com/watch?v=G-Kj8Re6spA&list=PLN3n1USn4xllF5t1GZhEwFQNDnStgupdB

import { Field, Formik } from "formik";
import React from "react";
import Layout from "../components/Layout";

import { RegisterMutationVariables, RegisterMutation } from "../../schemaTypes";

const registerMutation = gql`
  mutation RegisterMutation($email: String!, $password: String!) {
    register(email: $email, password: $password)
  }
`;

export default () => {
  return (
    <Layout title="Register page">
      <Mutation<RegisterMutation, RegisterMutationVariables>
        mutation={registerMutation}
      >
        {register => (
          <Formik
            validateOnBlur={false}
            validateOnChange={false}
            onSubmit={async (data, { setErrors }) => {
              try {
                const response = await register({
                  variables: {
                    data
                  }
                });
                console.log(response);
              } catch (err) {
                console.log(err)
              }
            }}
            initialValues={{
              email: "",
              password: ""
            }}
          >
            {({ handleSubmit }) => (
              <form onSubmit={handleSubmit}>
                <Field
                  name="email"
                  placeholder="email"
                  component={InputField}
                />
                <Field
                  name="password"
                  placeholder="password"
                  type="password"
                  component={InputField}
                />
                <button type="submit">submit</button>
              </form>
            )}
          </Formik>
        )}
      </Mutation>
    </Layout>
  );
};

答案 1 :(得分:0)

好吧,代码格式使您很难看到您的代码,但是,通常,您可以将表单放入突变中,然后将突变函数用作表单的提交函数,如下所示:

        // linux setting
        app.UseForwardedHeaders(new ForwardedHeadersOptions
        {
            ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
        });

        app.UseAuthentication();
        app.UseHttpsRedirection();

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{api}/{controller}/{action}");
        });

}

答案 2 :(得分:0)

我同时使用了 formik apollo突变。 而不是使用另一个Mutation标签(让他们厌烦了!让您的代码看上去如此肮脏如此之快),我在函数中使用了 this.props.mutate()

当您在graphql的影响下导出具有该突变的组件时,可以在道具中找到您的突变。您很快就会看到它。

这是组件的主render()函数内部的表单外观

< Formik
initialValues = {
  {
    title: '',
  }
}
onSubmit = {
  this.submitMutation // my own function
}
render = {
  this.renderForm // my own function that just returns views and texts tags
}
validationSchema = {
    Yup.object().shape({
      title: Yup
        .string()
        .required('title is required'),
    })
  } >

  <
  /Formik>

下面是我的提交突变函数,被formik调用

submitMutation = () => {
  return this.props.mutate({
    variables: {
      title: this.state.title,
    },
  })
}
最后,完成此操作

export default graphql(addBillMutation)(CreateBill);

全部代码。.请根据您的情况进行调整

import React from 'react';
import {
    StyleSheet, Text, Image, View, TextInput, Picker, TouchableOpacity, ScrollView, KeyboardAvoidingView
} from 'react-native';

import Header from './header';
import { graphql } from 'react-apollo';
//import mutation query from queries
import { getBillsQuery, addBillMutation } from './queries/queries';
import { Formik } from 'formik';
import * as Yup from 'yup';

class CreateBill extends React.Component<any, any>  {
    constructor(props: any) {
        super(props);
        this.state = {
            title: "",
            loading: false,
        }
        this.submitMutation = this.submitMutation.bind(this);
    }

    submitMutation = () => {
        return this.props.mutate({
            variables: {
                title: this.state.title,
            }
        })
    }

    _handleSubmit = async (values: any) => {
        //setting values here, when form is already validated by yup in formika
        this.setState({
            title: values.title,
        });
        try {
            //set loading to true before sending request
            this.setState({ loading: true });
            await this.submitMutation()
                .then(({ data }) => {
                  //response handling
                }).catch((error) => {
                    this.setState({ loading: false });
                    //error handling
                });
        } catch (error) {
            //handle error
        }
    }

    renderForm = (formikProps: any) => {
        const {
            values, handleSubmit, handleBlur, handleChange, errors,
            touched, isValid, isSubmitting
        } = formikProps;

        return (

                <ScrollView>
                            <View>
                                        <TextInput
                                            style={styles.input}
                                            value={values.title}
                                            placeholder="title goes here"
                                            onChangeText={handleChange('title')}
                                            onBlur={handleBlur('title')}
                                        />
                                    </View>
                                        {(touched.title && errors.title) ? touched.title && errors.title : "Required"}
                                    </Text>
                                </View>
                                        
                            </View>
                </ScrollView>
        );
    }
    render() {
        return (
            <View>
                <Header />
                <View>

                    <Formik
                        initialValues={{ title: ''}}
                        onSubmit={this._handleSubmit}
                        render={this.renderForm}
                        validationSchema={Yup.object().shape({
                            title: Yup
                                .string()
                                .required('title is required'),
                        })}
                    >

                    </Formik>
                </View>
            </View>
        );
    }
}

export default graphql(addBillMutation)(CreateBill);