TIL/항해산 TIL

38 내 페이지의 edit 기능 구현하기

매망쩔 2023. 1. 11. 15:30

초기에

페이지에서 수정을 누르면  

이렇게  글자를 변경가능해야 했는데 초기에는 변경이 되지 않았다.

 

 <div>
                  <h2> 제목 </h2>
                  <input
                    type="text"
                    value={detail.title}
                    onChange={(ev) => {
                      //   console.log(ev.target.value);
                      //   recodTitle = ev.target.value;
                      const { value } = ev.target;
                      setRecord({
                        ...record,
                        title: value,
                      });
                    }}
                  />
                </div>

위에서 detail은 서버에서 받아온 값이다. 그렇기 떄문에 set을 써도 수정이 되지 않는다.

따라서 버튼을 계속 입력해서 set을 하려고 해도 value값이 detail값을 받아온다.

따라서 해결한 코드는 다음과 같다.

  <DetailTitle>
                <div>
                  <h2> 제목 </h2>
                  <input
                    type="text"
                    value={record.title}
                    onChange={(ev) => {
                      //   console.log(ev.target.value);
                      //   recodTitle = ev.target.value;
                      const { value } = ev.target;
                      setRecord({
                        ...record,
                        title: value,
                      });
                    }}
                  />
                </div>

 

 

-------------------------

진행을 하다보니 비동기 작업이 굉장히 많다. 하지만 강의내용에서는  axios 사용할 때, toolkit을 따로 활용하지 않았어서, 해당 방법을 모방하다 보니, 에러가 수정이 되질 않는다..

 

비동기 작업이 있을때는 미리 비동기 작업 여부를 확인한다음에 toolkit먼저 구상하자.. 

페이지의 edit까지 억지로 구성해놓은 다음에, 수정을 하려하니 에러도 많이 뜨고, 꼬인 느낌이다.

 

대대적인 개편이 들어가야하지만 코드가 아까워서 업로드해본다

 

import React from "react";
import { useNavigate, useParams } from "react-router-dom";
import { useSelector } from "react-redux";
import styled from "styled-components";
import { useDispatch } from "react-redux";
import { useEffect, useState } from "react";
import { __getRecords } from "../redux/modules/recordsSlice";
import axios from "axios";
const DtBox = styled.div`
  margin: 20px auto;
  padding: 0 24px;
  width: 600px;
  /* height: 400px; */
  border: 1px solid rgb(238, 238, 238);
  display: flex;
  flex-direction: column;
  -webkit-box-pack: justify;
  justify-content: flex-start;
  flex-wrap: nowrap;
  gap: 20px;
`;

const DtConHead = styled.div`
  display: flex;
  height: 80px;
  -webkit-box-pack: justify;
  justify-content: space-between;
  -webkit-box-align: center;
  align-items: center;
`;

const GoBack = styled.button`
  border: 1px solid rgb(221, 221, 221);
  height: 40px;
  width: 120px;
  background-color: rgb(255, 255, 255);
  border-radius: 12px;
  cursor: pointer;
`;
const DetailTitle = styled.div`
  display: block;
  font-size: 2em;
  margin-block-start: 0.67em;
  margin-block-end: 0.67em;
  margin-inline-start: 0px;
  margin-inline-end: 0px;
  font-weight: bold;
`;

function Detail() {
  const dispatch = useDispatch();

  const param = useParams();
  const navigate = useNavigate();
  const { isLoading, error } = useSelector((state) => state.records);
  const records = useSelector((state) => state.records.records);
  const detail = records.find((detail) => detail.id === parseInt(param.id)); //새로고침 시에는 바로 뜨지 않음. 그래서 옵셔널 체이닝 써야함.
  useEffect(() => {
    dispatch(__getRecords());
    // return axios.patch(`http://localhost:3001/records/${detail.id}`, {
    //   ...detail,
    //   editable: false,
    // });
  }, [dispatch]);
  const goBack = () => {
    navigate(-1);
  };
  const onEditdableHandler = async (detail) => {
    const edit = { ...detail, editable: !detail.editable };
    await axios.patch(`http://localhost:3001/records/${detail.id}`, edit);
    dispatch(__getRecords());
  };

  const [record, setRecord] = useState({
    title: detail?.title,
    content: detail?.content,
    editable: false,
  });

  //   if (detail) {
  //     setRecord({ ...record, title: detail.title, content: detail.content });
  //   }
  const onEditHandler = async (detail, record) => {
    console.log(detail);
    console.log(record);
    const edit = { ...detail, ...record };
    await axios.patch(`http://localhost:3001/records/${detail.id}`, edit);
    dispatch(__getRecords());
  };

  if (isLoading) {
    return <div>로딩 중....</div>;
  }

  if (error) {
    return <div>{error.message}</div>;
  }
  //   console.log(!detail?.id);
  try {
    if (detail.editable) {
      return (
        <div>
          <form
            onSubmit={(e) => {
              e.preventDefault();
              onEditHandler(detail, record);
              navigate();
            }}
          >
            <DtBox>
              <DtConHead>
                <div> ID : {detail?.id}</div>
              </DtConHead>
              <div>작성자 : {detail?.writer}</div>
              <DetailTitle>
                <div>
                  <h2> 제목 </h2>
                  <input
                    type="text"
                    value={record.title}
                    onChange={(ev) => {
                      //   console.log(ev.target.value);
                      //   recodTitle = ev.target.value;
                      const { value } = ev.target;
                      setRecord({
                        ...record,
                        title: value,
                      });
                    }}
                  />
                </div>
              </DetailTitle>
              <div>
                <h2>내용</h2>
                <input
                  type="text"
                  value={record.content}
                  onChange={(ev) => {
                    const { value } = ev.target;
                    setRecord({
                      ...record,
                      content: value,
                    });
                  }}
                />
              </div>
            </DtBox>
            <button onClick={() => onEditdableHandler(detail)}>
              {detail.editable ? "취소" : "수정"}
            </button>
            <button> 완료</button>
          </form>
        </div>
      );
    } else if (!detail.editable) {
      //false일때 먼저 불러오기
      return (
        <div>
          <DtBox>
            <DtConHead>
              <div> ID : {detail?.id}</div>
              <GoBack onClick={goBack}> 이전으로 </GoBack>
            </DtConHead>
            <div>{detail?.writer}</div>
            <DetailTitle>{detail?.title}</DetailTitle>
            <div>{detail?.content}</div>
          </DtBox>
          <button onClick={() => onEditdableHandler(detail)}>
            {detail.editable ? "취소" : "수정"}
          </button>
        </div>
      );
    }
  } catch (error) {}
}

export default Detail;