ryu110
@ryu110

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

Formikの中でmutationを使用したい

Formikを使用してFormの値を入力をして送信した時にcreateできるようにしたいです。
Fieldを使用すれば簡単にFormができることはわかりました。
useStateなどを使用して値を保持してcreatePostしたいです。
ここから先試してみましたがいまいちわからないです。
Fieldを使用したmutationの使い方を教えてください。

FrontEnd

import { useMutation } from '@apollo/client'
import { gql } from '@apollo/client'
import { Formik, Form, Field, ErrorMessage } from 'formik'
import { useState } from 'react'
import * as Yup from 'yup'

const CREATE_POST = gql`
  mutation createPost($title: String!, $content: String!) {
    createPost(title: $title, content: $content) {
      title
      content
    }
  }
`

export interface PostingFormType {
  title: string
  content: string
}

const initialValues = {
  title: '',
  content: '',
}

const validationSchema = Yup.object().shape({
  title: Yup.string()
    .min(5, `5文字以上の文字を入力してください`)
    .required('必須項目です'),
  content: Yup.string().required('必須項目です'),
})

const PostingForm = () => {
  const [title,setTitle] = useState('')
  const [content,setContent] = useState('')
  const [createPost, { error }] = useMutation(CREATE_POST, {
    variables: {
      title: title,
      content: content,
    },
    refetchQueries: ['allPosts'],
  })
  if (error) {
    console.log('error')
  }

  return (
    <div>
      <h1>Posting Form</h1>
      <Formik
        initialValues={initialValues}
        onSubmit={(values, { setSubmitting, resetForm }) => {
          createPost({ variables: values })
          setTimeout(() => {
            alert(JSON.stringify(values, null, 2))
            setSubmitting(false)
            resetForm()
          }, 400)
        }}
        validationSchema={validationSchema}
      >
        {({ isSubmitting }) => (
          <Form>
            <Field type="title" name="title" values={setTitle}/>
            <ErrorMessage name="title" component="div" />
            <Field type="content" name="content" values={setContent}/>
            <ErrorMessage name="content" component="div" />
            <button type="submit" disabled={isSubmitting}>
              Submit
            </button>
          </Form>
        )}
      </Formik>
    </div>
  )
}

export default PostingForm

BackEnd

新規でcreateなのでResolverにあるauthorのところが違うと思いますが、どのように記述するのかがわかりません。authorはユーザのidどリレーションであり、必須です。

import express from "express";
import cors from "cors";
import { PrismaClient } from "@prisma/client";
import { graphqlHTTP } from "express-graphql";
import { makeExecutableSchema } from "@graphql-tools/schema";

export interface Context {
  prisma: PrismaClient;
}

const prisma = new PrismaClient();

const typeDefs = `
  type User {
    email: String!
    name: String
  }
  type Post {
    id: String!
    title: String!
    content:String!
  }
  type Query {
    allUsers: [User!]!
    allPosts: [Post!]!
  }
  type Mutation {
    createPost(
      title: String!
      content:String!
      ):Post!
  }
`;

const resolvers = {
  Query: {
    allUsers: () => {
      return prisma.user.findMany();
    },
    allPosts: () => {
      return prisma.post.findMany();
    },
  },
  Mutation: {
    createPost: (parent: any, args: any, context: any, info: any) => {
      const newPost = prisma.post.create({
        data: {
          title: args.title,
          content: args.content,
          author: {
            connect: {
              id: 1,
            },
          },
        },
      });
      return newPost;
    },
  },
};

export const schema = makeExecutableSchema({
  resolvers,
  typeDefs,
});

const app = express();
app.use(cors());
app.use(
  "/graphql",
  graphqlHTTP({
    schema,
    graphiql: true,
  })
);

if (process.env.NODE_ENV !== "production") {
  require("dotenv").config();
}

const PORT = process.env.PORT || 3001;

app.listen(PORT, () => {
  console.log(`接続完了! ${PORT}.`);
});

0

1Answer

まずコードが読めないのでコードの挿入方法を読んだほうがいいです。

export interface PostingFormType {
  title: string;
  content: string;
}

```tsx
export interface PostingFormType {
title: string;
content: string;
}
```

こうすれば綺麗に表示できます。

あとは基本的にfunctional componentの書き方がおかしい。

const PostingForm = () => ( ... )

これはアロー関数でreturnを省略して返す書き方です。この場合、今回のように途中でconstとかが使えず、直接値を返すような計算しか出来ません(トップレベルのブロックでの話)。

() => {return (value)} => () => return (value) => () => (value) => () => value と考えればretrunする時にconstが使えないのは分かると思います。

const PostingForm = () => {
  const ...

  return (<div>...</div>)
}

こうすればエラーになりません。

0Like

Comments

  1. @ryu110

    Questioner

    ご指摘ありがとうございます。全て編集いたしました。
    次に、本来の質問をお願いしたいです。
    backendoも載せときます
  2. @ryu110

    Questioner

    作成できました!!!!

Your answer might help someone💌