본문 바로가기

Else/Personal Blog Building

Beomlog - Post Page

Post Page를 이제 만들려고 한다. 먼저 Container 부터 만들어주자.

PostContainer를 이렇게 만들어 주었다. 이제 useEffect에서 컴포넌트가 마운트될때 getPost 액션이 실행되도록 하려고 한다.

 

import React, { useEffect, useState } from 'react';
import { PostState, getPost } from '../../Modules/post';
import { useSelector, useDispatch } from 'react-redux';
import { RootState } from '../../Modules';
import './PostContainer.scss';
import Loader from '../../Components/Shared/Loader';

type PostContainerProps = {
    postId: string
}

function PostContainer({ postId }: PostContainerProps) {

    const post: PostState = useSelector((state: RootState) => state.post);
    const dispatch = useDispatch();

    const [isLoading, setIsLoading] = useState(true);

    useEffect(() => {
        try {
            dispatch(
                getPost(postId)
            );
            setIsLoading(false);
        } catch (e) {
            console.log(e);
            setIsLoading(false);
        }
    }, [dispatch, postId]);

    if (post.error) {
        return <div>There is an error: {post.error}</div>;
    }

    return (
        <div className="post-container">
            {
                isLoading
                ? <Loader />
                : <>
                    <div>{postId}</div>
                    <h1>{post.title}</h1>
                    <h3>{post.category}</h3>
                    <div dangerouslySetInnerHTML={{__html: post.editorData}}></div>
                    <div>
                        <span>{post.uid}</span>
                        <span>{post.userData.email}</span>
                        <span>{post.userData.name}</span>
                        <div>{post.time.toString()}</div>
                    </div>
                </>
            }
        </div>
    );
}

export default PostContainer;

다음과 같이 작성해 준 후 실행하였더니

잘 되긴 한다. 근데 어딘가 이상한 부분들이 많다. no userdata는 로그인 하지 않은 상태에서 작성하여서 그렇다 쳐도 타임이 이상하게 작동되는것 같다. 이것은 나중에 고치도록 하겠다. 파이어스토어 데이터베이스를 다시 확인해보니 timestamp 형식으로 작성되있긴 하지만 시간 자체는 정확하게 기입이 되있기때문에, 나중에 고치도록 하겠다.

 

이제 update와 delete를 만들 차례이다. 먼저 쉬운 delete부터 만들어주자. button을 하나 만들어서 누르면 deletePost를 dispatch하도록 할 것이다. 먼저 자신이 쓴 글만 delete할 수 있어야 하기 때문에, post.uid와 현재 state상의 user.uid가 같은지를 비교해주는 isWriter라는 boolean 변수를 만들어준다.

isWriting이 true이면 delete와 update (edit post) 버튼이 뜨도록 만들것이다.

 

그리고 onClickDeleteButton 메서드를 다음과 같이 작성해 주었다.

그리고 버튼 두개를 만든 후, 실제 코드를 실행해 보았더니,

이렇게 버튼들이 잘 뜬다.

파이어베이스에도 잘 업데이트가 되었다. 이제 버튼을 눌러 삭제를 해보면, Delete Successful 메세지도 잘 뜨면서 데이터베이스에서도 잘 삭제가 되는 것을 볼 수 있다. 그리고 이제 DELETE_POST를 하였을 때 state를 어떻게 해줄 지 리듀서에 작성을 해주자.

대강 이런식으로 작성을 해주었다. 이제 UPDATE_POST를 어떻게 처리할지를 정해야된다.

 

먼저, UPDATE_POST를 하기 전에는 state에 전에 자신이 봤던 post의 내용이 들어가 있을 것이다. post의 수정은 무조건 Post Page에서만 가능하고, post가 로드가 되어야만 수정을 할 수 있는 버튼이 뜨기 때문에, 기본적으로 가정할 수 있는 것은 post의 state에 자신이 작성했고 자신이 방금 읽은 post의 내용들이 그대로 들어가 있다는 것이다. 그리고 update를 할 때에는 그것들이 필요하다. 따라서 update 페이지로 갈 때에는 state에 있던 내용들이 그대로 들어갈 것이다. 또한, UPDATE_POST 액션을 발동시켰을 때에는 postId만 같고 나머지는 전부 새로 덮어 씌워야 하기 때문에, payload로 넘어온 내용을 state에 저장을 하면서, UPLOAD_POST와 비슷한 작업을 수행하도록 할 것이다.

 

먼저 UpdatePage를 만들어주자. 대략적인 뼈대는 WritingPage와 같지만, 받아오는 값들이 있도록 설정해줄 것이다. 먼저 EditorContainer에 새로운 prop을 만들어주자.

이제 각 initialState 변수들이 isUpdating이 true라면 state.post에서 데이터들을 받아와서 그들의 initialState로 쓰도록 할 것이다.

이제 UpdatePage를 만들어 주고 링크한 뒤, 라우터로 링크시켜주고, updatePost를 디스패치해주는 것을 isUpdating을 통해 판단 후 EditorContainer의 Submit버튼의 onClick에서 진행하도록 해주자.

즉 EditorContainer의 Submit버튼은 isUpdating이 true라면 update를 진행해주고 false라면 upload를 진행해준다. 이제 Editor.js 컴포넌트의 prop에 data라는 항목을 추가해주자. 그러면

이와 같이 쓸 수 있다. defaultProps로써 data를 일단은 빈공간으로 해주되, 만약 data가 넘어온다면 (즉 업데이트 중이라면), 에디터에 데이터가 그대로 뜰 것이다. 이제 이 모든것들을 적용한뒤 업데이트를 해보면,

update할 때 필요한 것들이 잘 나오는 것을 볼 수 있다. 이후 뒤에 아무 글자나 넣고 Submit을 눌러보면, 

Update도 아주 잘된다. 이로써 CRUD는 모두 끝이 났다. 다음은 카테고리 작업과 홈 또는 카테고리에 따라서 포스트를 볼 수 있도록 해줄것이다.

'Else > Personal Blog Building' 카테고리의 다른 글

Beomlog - Category and Firebase  (0) 2020.07.14
Beomlog - Categories and User Settings Update Page  (0) 2020.07.14
Beomlog - Writing Page & Upload  (0) 2020.07.14
Beomlog - Redux, Redux-saga - post  (0) 2020.07.13
Beomlog - CKEditor5  (0) 2020.07.13