[미니 프로젝트] Jelog 만들기 #3

박제현·2023년 7월 23일
1

jelog 만들기

목록 보기
3/15

🐵 포스트 페이지 만들기.

새로운 페이지를 만들기 전, 역시나 당연하게 velog 화면 분석부터 진행하자.
헤더, 바디, 사이드 바로 구분 짓고 html 구조를 작업하면 될 것 같다.

그 포스트 화면을 구성하기 전에.. 일단 해당 포스트의 페이지인지 부터 구분 지을 필요가 있다.
각각의 포스트 마다 내용이 달라질 것이기 때문에, 이전과 같이 링크를 하나로 지정하면 안된다는 이야기이다.

URL에 포스트 ID 값을 지정해서 넘겨주면 될 것 같은 생각이 들었다.

	<Route
    	path="/post/:id"
        element={<PostPage posts={postList} setPost={setPostList} />}
	/>

위와 같이 path를 "/post/:id" 로 지정하면, /post/" id 변수 " 가 할당된 URL이 만들어진다.

      <Link to={`/post/${item.id}`} key={index} className="postBox">
        <div className="innerBox">
          <div className="thumbnail">THUMBNAIL</div>
          <span className="title">{item.title}</span>
          <span className="content">{item.content}</span>
        </div>
        <span className="date">{item.date}</span>
      </Link>

포스트 페이지로 이동할 Link 태그에 id값을 추가 해주면 된다.
주소창을 보면 localhost:3000/post/0 으로 제대로 라우팅 됐음을 확인할 수 있다.
( 이 부분은 https://www.youtube.com/watch?v=vI-XtN_Zdfg 해당 유튜브 강의 영상을 참고하였다. )

🏊‍♂️ CRUD 구현하기.

일단 Create, Read 는 일단 반쪽자리 구현은 완성했다.
게시글 포스팅하기, 포스팅 된 게시글 읽기.. 이제 포스팅 된 게시글 수정하기 기능과 포스팅 된 게시글 삭제하는 기능을 추가해보자.

먼저 쉬워보이는 포스팅 삭제 기능 부터 구현해보자.
포스트를 삭제하려고 할 때, 바로 삭제되지 않고 모달 팝업을 띄워 한 번더 사용자에게 확인을 받도록 설정한다.
모달 팝업은 react-modal 라이브러리를 활용하여 만들었다.

기억할 점.


모달 팝업은 엘리먼트의 최상단에 위치하여야 한다.

  const handleButtonConfirm = () => {
    closeModal();
    const newPosts = [...posts];
    newPosts.splice(postID, 1);
    setPost(newPosts);
  };

모달 팝업에서 확인 버튼을 눌렀을 때 동작하는 함수이다.
모달 팝업을 닫아주고, 새로운 포스트 배열을 선언한다. 새로운 포스트 배열에 기존 포스트 배열을 복사하고, splice() 함수를 사용하여 해당 포스트 ID에 위치한 포스트를 삭제해준다.
그리고 useState를 사용해 React에게 상태가 변경됨을 알려준다.

이렇게 쉽게 삭제 기능이 구현되었다.

다음으로, 포스팅 된 게시물을 수정하는 기능을 구현해보자.
일단 수정할 페이지 화면은 새로운 글 쓰는 화면과 비슷하게 구성한다.
달라진 점은 URL이 /write가 아닌 /write/id 인 점이다.
마지막에 붙어있는 포스트 ID 값으로 수정할 게시글의 정보를 받아온다.

  const postID = useLocation().pathname.split("/")[2];
  const post = posts.find((item) => item.id === postID);

useLocation 함수를 사용해 URL 정보를 받아와 마지막 ID 값만 잘라낸 postID를 선언한 뒤, 해당 ID를 가진 게시글을 찾는다.

  const handleModPost = () => {
    const today = new Date();
    const title = titleTextareaRef.current.value;
    const content = contentTextareaRef.current.value;
    const modifiedPost = {
      id: postID,
      title: title,
      content: content,
      likesCount: post.likesCount,
      date: today.toLocaleDateString(),
    };
    const updatedPosts = posts.map((item) =>
      item.id === postID ? modifiedPost : item
    );

    setPost(updatedPosts);
  };

리액트가 상태 변화를 감지할 수 있도록, 직접 post를 변경하지 않고 새로운 modifiedPost 객체를 선언하여 useState를 이용해 수정한다.
직접 post 값을 변경하면 리액트가 상태 변화를 감지하지 못하고 화면이 새롭게 갱신되지 않는다. 그 동안 왜? 상태가 변했는데 값이 갱신이 안되는지 몰랐는데, Update 기능을 구현하면서 그 이유를 알게됐다! 😁

👮‍♂️ 게시된 포스팅들 정렬하기.

이제 CRUD 기능을 얼추 만들었으니, 트렌딩 게시글과 최신 게시글을 정렬하는 코드를 만들어보자.
우선, 트렌딩 게시글을 정렬하기 위한 기준이 필요하다.
그 기준은 사이드 바의 Like Count를 활용했다.

    const newPost = {
      id: posts.length.toString(),
      title: title,
      content: content,
      date: today.toLocaleDateString(),
      likesCount: 0,
    };

따라서, post의 JSON 형태는 위와 같이 변경됐다.

  const trendingPostList = [...postList].sort(
    (a, b) => b.likesCount - a.likesCount
  );
  
  const trendingPosts = trendingPostList.map((item, index) => {
    return (
      <Link to={`/post/${item.id}`} key={index} className="postBox">
        <div className="innerBox">
          <div className="thumbnail">THUMBNAIL</div>
          <span className="title">{item.title}</span>
          <span className="content">{item.content}</span>
        </div>
        <span className="date">{item.date}</span>
      </Link>
    );
  });

App.js 에서 trendingPostList를 따로 선언해주고, 해당 배열로 trendingPosts 엘리먼트 배열을 만들어낸다.
처음에는 그냥 MainPage 에서 프롭스로 받아온 posts를 정렬해주려고 했는데, 애초에 넘겨주는 props가 엘리먼트 배열이기 때문에..
App.js 에서 정렬된 엘리먼트 배열을 넘겨주기로 했다.

최신 게시글 정렬은 뭐.. 똑같이 하면 된다!

잘 작동하는 것 봐... 기분이 👍👍👍

😎 3일차 결과물.

이렇게가 오늘의 결과물이다. 이제.. 로그인 기능 정도를 다음에 구현해 볼 예정이다.
이제 어느정도 리액트의 상태 변화에 대해 개념이 슬 잡혀가는 것 같다.
Jelog의 J는 완성된 것 같다. 🤣

📚 오늘의 질문들..

  • 배열에서 특정 인덱스 값을 가진 노드를 삭제하는 방법

    배열에서 특정 인덱스 값을 삭제하고 싶을 때 'splice()' 메서드를 사용하면 된다. param는 TargetKey, 1 을 넘겨주어 TargetKey부터 몇 개의 값을 잘라낼 것인지 결정하는 값을 넣어준다.

  • 배열을 likesCount 기준으로 내림차순 정렬하는 방법

    배열을 정렬하려면 'sort()' 메서드를 사용하면 된다.
    sort((a, b) => b.likesCount - a.likesCount)
    위 코드를 설명하면 비교 인자로 두 개의 a, b 인자를 받는다.
    이 함수의 반환 값에 따라서 배열의 요소들이 정렬 된다.
    만약 반환 값이 0보다 작으면 a 가 b 보다 앞에 위치하도록 정렬된다.
    반환 값이 0이면 순서 변경이 없고, 크면 b 가 a 보다 앞에 위치하도록 정렬된다.

  • 사용자 지정 CSS 속성 사용하기

    :root {
      --velog-green: rgb(61, 182, 61);
      --velog-green-bright: rgb(61, 210, 61);
      --velog-grey: rgb(235, 235, 235);
      }

    어디서든지 접근할 수 있도록 :root 클래스에 선언하여 사용한다.
    사용할 때는 var(--velog-green) 과 같이 사용한다.

profile
닷넷 새싹

0개의 댓글