인프런 커뮤니티 질문&답변

중오님의 프로필 이미지
중오

작성한 질문수

[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스

수정뮤테이션 여러개가날라갑니다 ㅜㅜ myvariables로해도안되네여

해결된 질문

작성

·

366

·

수정됨

0

import { useMutation } from "@apollo/client";
import { useRouter } from "next/router";
import { useState } from "react";
import { CREATE_BOARD, UPDATE_BOARD } from "./BoardWrite.query";
import BoardWriteUI from "./BoardWrite.presenter"


export default function BoardWrite(props) {
  const [writer, setWriter] = useState("");
  const [password, setPassword] = useState("");
  const [title, setTitle] = useState("");
  const [contents, setContents] = useState("");

  const [WriteError, setWriteError] = useState("");
  const [passwordError, setPasswordError] = useState("");
  const [titleError, setTitleError] = useState("");
  const [ContentsError, setContentsError] = useState("");

  const [createBoard] = useMutation(CREATE_BOARD);
  const [updateBoard] = useMutation(UPDATE_BOARD)

  const router = useRouter();
  const [isActive,setIsActive] = useState(false)
  const onChangeWriter = (e) => {
    setWriter(e.target.value);
    if (e.target.value !== "") {
      setWriteError("");
    }
      if (e.target.value && password && title  && contents) {
        setIsActive(true);
      }else{
        setIsActive(false)
      }
  };
  const onChangePassword = (e) => {
    setPassword(e.target.value);
    if (e.target.value !== "") {
      setPasswordError("");
    }
      if (e.target.value && password && title && contents) {
        setIsActive(true);
      } else {
        setIsActive(false);
      }
  };
  const onChangeTitle = (e) => {
    setTitle(e.target.value);
    if (e.target.value !== "") {
      setTitleError("");
    }
      if (e.target.value && password && title && contents) {
        setIsActive(true);
      } else {
        setIsActive(false);
      }
  };
  const onChangeContents = (e) => {
    setContents(e.target.value);
    if (e.target.value !== "") {
      setContentsError("");
    }
      if (e.target.value && password && title && contents) {
        setIsActive(true);
      } else {
        setIsActive(false);
      }

  };

  const onClickSubmit = async () => {
    if (!writer) {
      setWriteError("작성자를입력해주세요");
    }
    if (!password) {
      setPasswordError("비밀번호를 입력해주세요");
    }
    if (!title) {
      setTitleError("제목을 입력해주세요");
    }
    if (!contents) {
      setContentsError("내용을 입력해주세요.");
    }
    if (writer && password && title && contents) {
      try {
        const result = await createBoard({
          variables: {
            createBoardInput: {
              writer,
              password,
              title,
              contents,
            },
          },
        });
        alert("등록완료");
        console.log(result.data.createBoard._id);
        router.push(`/boards/${result.data.createBoard._id}`);
      } catch (error) {
        alert(error.message);
      }
    }
  };

  const onClickUpdate = async () => {

    const myVariables = {}
    
    if(writer !== "") myVariables.writer = writer;
    if (title !== "") myVariables.title = title;
    if(contents !=="") myVariables.contents = contents;
    

    try{
      const result = await updateBoard({
        variables:{
          boardId:router.query.boardId,
          password:password,
          updateBoardInput:{
            title:title,
            contents:contents
          }
        }
      })
      router.push(`/boards/${router.query.boardId}`);
      alert("수정완료")
    }catch(error){
      alert(error.message)
    }
  }
  return (
    <BoardWriteUI
      isActive={isActive}
      isEdit={props.isEdit}
      WriteError={WriteError}
      passwordError={passwordError}
      titleError={titleError}
      ContentsError={ContentsError}
      onChangeWriter={onChangeWriter}
      onChangePassword={onChangePassword}
      onChangeTitle={onChangeTitle}
      onChangeContents={onChangeContents}
      onClickSubmit={onClickSubmit}
      onClickUpdate={onClickUpdate}
      data={props.data}
    />
  );
}

답변 5

0

중오님의 프로필 이미지
중오
질문자

강의보단 좀다르게해결햇지만 감사합니다!

0

중오님의 프로필 이미지
중오
질문자

https://github.com/jnwnddh/NEXTJS-single-project 깃주소입니다 아무리해도되질않습니다....죄송합니다

코드캠프님의 프로필 이미지
코드캠프
지식공유자

네! 중오님!

깃허브 다운받아 본 결과 정상적으로 작동하는 것 확인했습니다!

제목과 내용 중 제목만 입력했을 경우 내용이 없어지고, 내용만 입력했을 경우 제목만 없어지는 이유는, 사실 없어지는 것이 아니라 작성하지 않은 빈문자열 "" 로 수정이 완료됐기 때문이에요.

제목을 입력하고, 내용을 입력하지 않았다면 제목은 onChange가 작동하여 해당 함수 안에서 setTitle이 동작했기 때문에 title state가 변경되었겠지만, 내용은 입력하지 않았으므로 defaultValue 에 값이 보이더라도, 실제로 setContents가 동작하지 않았기 때문에 contents state는 ""(빈문자열)이 들어가 있는 상태입니다.

따라서 해당 state들이 전송되면, title은 변경되었지만 contents는 삭제된 것 처럼 보이게 되겠지요.

해당 문제를 해결하는 방법은 다음 강에서 진행되니, 계속해서 수강해 주세요.

감사합니다.

0

중오님의 프로필 이미지
중오
질문자

20221227_161848.pngconst myVariables = { boardId: router.query.boardId };저렇게넣으면 저런식으로 에러가계속나더라구여

중오님!
요청하는 variables의 형태를 자세히 살펴보시기 바랍니다.

updateBoard 시 제대로 된 graphql 요청을 보내시려면

variables: {
boardId: (여기에 게시글 아이디),
password: (비밀번호),
updateBoardInput: {
title: ... ,
contents: ...
}
}

형식으로 작성해주셔야합니다.
페이로드에서 받아오는 값과 우리가 넣어줘야할 값에서 어떤 부분에 차이가 있는지 확인해보시고 수정해보세요!

0

중오님의 프로필 이미지
중오
질문자

20221227_160826.png한개보내면한개가사라집니다

안녕하세요 중오님

혹시 내용을 수정했을 때에 제목이 사라진다는 말씀이신것같은데 맞나요?

우선 게시글을 수정하실 때는 먼저 기존에 작성되었던 게시글을 불러오는 것이 우선입니다.
1. router.query로 받아온 게시글 아이디로 작성된 게시글 정보 조회
2. 조회된 정보를 input에서 기본값으로 보여주기
3. 제목 혹은 내용을 수정
4. 만약 수정되지 않은 값이라면 기존에 작성된 값을 보내도록 저장

현재는 게시글 수정 시 작성된 게시글 정보를 조회해서 불러오는 로직이 작성되지 않은 것으로 보입니다.
이 부분 참고하셔서 수정해보시기 바랍니다!

추가로, 컴포넌트가 아닌 변수 선언 시에는 소문자로 시작하는 카멜케이스를 작성하셔야합니다.
WriteError와 ContentsError는 writeError, contentsError로 작성해주시는게 좋겠습니다.
또한, 현재 myVariables를 사용하고 계신데, 만약 title이나 contents가 있다면 myVariables 객체에 담아주고, 요청을 보낼 때는 variables 어디에도 사용되고 있지 않습니다. 참고되시기 바랍니다!

0

안녕하세요 중오님

수정 뮤테이션이 여러개 날아간다고 하셨는데 요청이 여러개 발생한다는 의미이실까요?
요청이 얼마나 발생되는지, 어떤 요청이 되고 있는지가 중요하기 때문에
개발자도구의 네트워크와, 해당 요청의 payload와 preview 캡쳐본 전달 부탁드립니다.

중오님의 프로필 이미지
중오

작성한 질문수

질문하기