Act99 기술블로그

[Nextjs] 주식사이트 만들기-3 프론트엔드 채팅 만들기 (Apollo client, graphQL, useForm) 본문

개발팁저장소/nextjs

[Nextjs] 주식사이트 만들기-3 프론트엔드 채팅 만들기 (Apollo client, graphQL, useForm)

Act99 2021. 12. 10. 19:43

결국 웹 소켓 사용하는것은 다음으로 미루기로 했다. (실제 채팅 어플은 웹소켓을 이용하지 않는다고 하고 다른 방법으로 우회할 방법을 찾았다.)

 

그래서 사용한 방법은 Subscription이 아닌, Query & Mutation 으로만 구현한 것이다.

 

먼저 Mutation 타입들을 만들어주었다.

 

- frontChatMutation.ts

export interface CreateChatDto {
  user: string;
  text: string;
}

export interface frontCreateChatMutation_createChat {
  __typename: "CreateChatDtoOutput";
  ok: boolean;
  error: string | null;
}

export interface frontCreateChatMutation {
  createChat: frontCreateChatMutation_createChat;
}

export interface frontCreateChatMutationVariables {
  createChatDto: CreateChatDto;
}

 

다음 gql tag를 이용해 mutation 을 가져와주었다.

 

 

const CREATE_CHAT = gql`
  mutation frontCreateChatMutation($createChatDto: CreateChatDto!) {
    createChat(input: $createChatDto) {
      ok
      error
    }
  }
`;

 

다음으로 useForm을 이용해 form의 input data 가 submit 될 때 데이터 핸들링을 해주어 DB에 채팅을 저장시켜주었다.

 

- Chat 전체코드

import React, { useEffect, useState } from "react";

import { useMutation, useSubscription } from "@apollo/client";
import { gql } from "@apollo/client";
import { SubmitHandler, useForm } from "react-hook-form";
import {
  frontCreateChatMutation,
  frontCreateChatMutationVariables,
} from "../../__generated__/frontChatMutation";

type Props = {
  width: number | undefined;
  height: number | undefined;
};

type Inputs = {
  user: string;
  text: string;
};

const CREATE_CHAT = gql`
  mutation frontCreateChatMutation($createChatDto: CreateChatDto!) {
    createChat(input: $createChatDto) {
      ok
      error
    }
  }
`;

const GET_CHAT = gql`
  query {
    chat {
      id
      user
      text
      createdAt
      updatedAt
    }
  }
`;

const Chat: React.FC<Props> = ({ width, height }) => {
  const {
    register,
    handleSubmit,
    getValues,
    formState: { errors },
  } = useForm<Inputs>();
  const onCompleted = (data: frontCreateChatMutation) => {
    const {
      createChat: { ok },
    } = data;
    if (ok) {
      console.log("Okay! Chat!");
    }
  };
  const [createChatMutation, { data: createChatMutationResult, loading }] =
    useMutation<frontCreateChatMutation, frontCreateChatMutationVariables>(
      CREATE_CHAT,
      { onCompleted }
    );

  const onSubmit: SubmitHandler<Inputs> = () => {
    if (!loading) {
      const { user, text } = getValues();
      createChatMutation({ variables: { createChatDto: { user, text } } });
    }
  };

  return (
    <div
      style={{
        width: 300,
        height: height == undefined ? undefined : height * 0.9,
      }}
      className=" bg-black flex flex-col justify-center items-center"
    >
      <div className=" w-72 h-5/6  bg-chartGray-default"></div>
      <form className="flex flex-col my-5" onSubmit={handleSubmit(onSubmit)}>
        <input
          className=" bg-gray-300 mb-2"
          {...register("user", { required: true })}
        ></input>
        <input
          className=" bg-gray-300 mb-2"
          {...register("text", { required: true })}
        ></input>
        <button className=" bg-gray-400" type="submit">
          {loading ? "로딩중..." : "전송"}
        </button>
      </form>
    </div>
  );
};

// const Messages = (chats: Chats) => {
//   return <div></div>;
// };

export default Chat;

 

 

결과물은

 

전송

 

 

postgresql DB

 

채팅이 잘 저장되고 있었다.

 

다음으로는 채팅 전송이 되었을 때 채팅 input 이 초기화되게끔 만들 것이다.

그리고 DB에 있는 채팅들을 채팅창에 직접 띄울 것이다. (gql Query 이용)

 

마지막으로 대대적인 CSS 작업을 할 것이다.

(화면크기 문제부터 window 사이즈를 다루는 hook 까지 전부 다.)

 

그 다음은 로그인 기능과 회원가입 기능을 만들어

로그인한 유저만 채팅이 가능하게 만들 예정이다.