23.1.28[Blog 결국 완성]

커피 내리는 그냥 사람·2023년 1월 28일
0

항해99

목록 보기
100/108

타입스크립트로 블로그 만들기(미완성 부분 완성)

다 만든 블로그

23.1.28 기준

오늘 작업 : Component 나눠서 타입 지정 후 toggle 다 따로 뜨게 하기

  • TodoList 수정 형태에서 토글이 한 번에 뜨는 것 방지

설치한 내용들

  • db.json
  • axios
    (위 내용은 이미 설치한 것들)

원리

  • MyPost라는 Component와 타입을 지정해주는 interfaces 컴포넌트를 따로 나눠서 저장
  • 이후 각 컴포넌트에서 interfaces의 타입형 불러오고, 컴포넌트 간 props 전달 형식 연결 후 토글 설정(MyPost에서 토글 설정)

주요 코드

(Blog.tsx : 전체 코드가 있는 파일)
mport MyPost from './MyPost';
import {Content} from './interfaces'
// 만든 컴포넌트 import
...
...
  // 글 수정하기
  const onEditContent = async (content : Content) => {
    // 제목, 컨텐츠 같이 고칠 수 있게 하기
    axios.put(`http://localhost:3001/contentList/${content.id}`, {
      title : content.title,
      content : content.content
	// 객체형태이므로 content.~로 불러옴
    })
    const { data } = await axios.get('http://localhost:3001/contentList')
    setContentList(data)
    // 새로고침 안 해도 나오게 get 처리
  }
...
...

{contentList.map((content) => {
        return (
          <Posts>
          <Post>
          <h4>{content.title}</h4>
          <p>{content.content}</p>
          <MyPost content={content}
            key = {content.id}
            handleDelete = {deleteContent}
            handleSave={onEditContent}/>
            {/* props로 전달할 값 정하기 */}
        </Post> 
        </Posts>
        )
      })}
(interfaces.ts)
export interface Content {
  id: number,  
  title?: string,
  content?: string
}
// type 설정
(MyPost.tsx)
import React, {useState} from 'react'
import { Content } from './interfaces'
import styled from "styled-components";

// 먼저 MyPost로 컴포넌트 나눴어야 함.

// interfaces에서 타입 정한거 가져오기
interface PostProps {
  content : Content,
  handleSave : (content : Content) => void,
  handleDelete : (id: number) => void
}
const MyPost : React.FC<PostProps> = ({content, handleSave, handleDelete}) => {
// props 설정한 값 및 함수 가져오기
// 토글값 설정
const [toggle, setToggle] = useState<boolean>(false)
const toggleMenu = () => {
    setToggle(!toggle)
}

// 임시의 content값 설정
  const [tempContent, setTempContent] = useState<Content>(content)
  const save : () => void = () => {
    handleSave(tempContent)
    setToggle(false)
  }
  return (
    <div>
      <DelBtn onClick={() => {
          const result = window.confirm("이 작성글을 지우실꺼에요?")
          // 글 지울것인지 아닐지 물어보기 기능 : 사용자 편의 증가
          if(result) {
            return handleDelete(content.id);
          }else{
            return;
          }
        }
          }>삭제</DelBtn>
          <EditBtn onClick={toggleMenu}>수정</EditBtn>
          {toggle ? (
            <EditDiv>
              <input name='content' placeholder="수정하는 제목(15자 이내)" maxLength={15} value={tempContent.title} onChange={(event) => {setTempContent({
                ...tempContent, title : event.target.value
              })}}/>
              {/* 제목 고치는 Input, value를 설정해서 미리 값을 볼 수 있게 해준다. */}
              <textarea name='content' placeholder="수정하는 내용(200자 이내)" maxLength={200} value={tempContent.content} onChange={(event) => {setTempContent({
                ...tempContent, content : event.target.value
              })}}/>
              {/* // 내용 고치는 textarea, value를 설정해서 미리 값을 볼 수 있게 해준다. */}
              <br/>
              <EditComBtn onClick={() => save()}>수정완료</EditComBtn>
            </EditDiv>
          ) : null}
    </div>
  )
}

고민한 점

  • 적어놓은 interfaces.ts를 어떤 식으로 불러올지 고민 많이 함.
  • 커뮤니티에 물어본 대답은 axios를 쓰지 않고 쓴 내용이었기에 거기에 맞춰서 어떻게 적용할지 고민함.

문제점 해결 포인트

  • 토클값이 같아서 모든 토글이 다 열리는데 이걸 해결 못 함. => 컴포넌트를 나눠서 하면 한 게시물에 하나의 토글만 만들어진다. 기존 코드는 모든 토글이 열리게 된 코드였음. 즉 한 파일로 모든 걸 만들 순 없다.

최종 교훈 : 타입스크립트는 Todo 형태도 생각보다 어렵다. 많이 공부해야겠다. 다른 것도 만들어보자. 그리고 개발 혼자 하는거 아니다.

profile
커피 내리고 향 맡는거 좋아해요. 이것 저것 공부합니다.

0개의 댓글