React/게시판만들기 v2.

[React][CRUD] 게시판 만들기 All in One - (Issue.1) \n 을 <br /> 변경하기

binaryJournalist 2021. 5. 13. 15:15
반응형

 

 

 

목차 돌아가기:

https://binaryjourney.tistory.com/pages/ReactCRUD-create-board-tutorial-v2

 

[React][CRUD] create-board-tutorial-v2

* 인용시 출처 부탁드립니다. 완성 소스 code: github.com/cruellaDev/react-create-board-v2 cruellaDev/react-create-board-v2 updated version of react-create-board. Contribute to cruellaDev/react-create-..

binaryjourney.tistory.com

 

 

 

textarea 태그에서 줄바꿈이 포함된 글은 \n 을 포함하여 서버에 저장된다.

 

탭의 경우 \t 로 들어간다.

 

html editor 를 이용하게 되면 자동으로 replace 를 해줄테니 이러한 문제가 생기지 않겠지만

 

v2 소스는 아무런 스타일도 다른 UI 도 사용하지 않았기 때문에 string 과 함께 있는 태그의 경우 리액트에서 태그로 읽히지 않고 string과 함께 렌더링될 수 있다.

 

 

 

만들면서 긴 문장이나 문단으로 테스트하지 않았기 때문에 코드 작성시에는 이런 문제를 생각하지 못하였다.

 

 

구독자 myurm 님 덕분에 발견할 수 있었다.

 

 

 

이슈 해결을 위해 아래 사이트를 참고했다.

 

 

https://velopert.com/1896

 

[React.js] Tip: string 형태의 html을 렌더링하기, newline(\n) 을 BR 태그로 변환하기 | VELOPERT.LOG

React 매뉴얼의 “Dangerously Set innerHTML” 페이지에 따르면, React에서는 cross-site scripting (XSS) 공격을 막기 위하여, 렌더링 메소드 내부에서 html 태그가 담겨있는 string 형태를 렌더링하면, 태그가 안

velopert.com

 

 

바뀐 views/Article.js 의 소스는 아래와 같다.

 

// Article.js

import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useHistory, useParams } from 'react-router-dom';
import Comment from './Comments';
import { articleActions } from '../slices/articleSlice';

function Article() {
    const params = useParams();
    const { article, status, statusText } = useSelector((state) => state.articleReducer);
    const boardList = useSelector((state) => state.boardReducer.boardList);
    const dispatch = useDispatch();
    const history = useHistory();

    function onClickUpdateButton() {
        history.push(`/update/${params?.articleId ?? 0}`);
    }

    function onClickDeleteButton() {
        if (!window.confirm("삭제하시겠습니까?")) return false;
        dispatch(articleActions.deleteArticle());
    }

    useEffect(() => {
        dispatch(articleActions.getArticle(params?.articleId ?? 0));
    }, [dispatch, params?.articleId]);
    return (
        <>
            {
                status === 200 ?
                    <>
                        <div>
                            <div>
                                <div>
                                    <div>
                                        <button onClick={onClickUpdateButton}>수정</button>
                                    </div>
                                    <div>
                                        <button onClick={onClickDeleteButton}>삭제</button>
                                    </div>
                                </div>
                                <div>
                                    <span>게시판: </span>
                                    <span>
                                        {
                                            boardList.length > 0 &&
                                            boardList.find((board) => board.id === parseInt(article?.boardId))?.name
                                        }
                                    </span>
                                </div>
                                <div>
                                    <div><span>제목: </span><span>{article?.title ?? ""}</span></div>
                                    <div><span>조회수: </span><span>{article?.views ?? ""}</span></div>
                                    <div><span>작성일시: </span><span>{(article.insertDate) ? new Date(article?.insertDate).toLocaleString() : ""}</span></div>
                                    <div><span>내용: </span><span>{article?.content?.split("\n")?.map(line => <span>{line}<br/></span>)}</span></div>
                                </div>
                            </div>
                            <div>
                                <Comment articleId={params?.articleId ?? 0} />
                            </div>
                        </div>
                    </>
                :
                    <div>
                        <div>
                            <span>{status}</span>
                        </div>
                        <div>
                            <span>{statusText}</span>
                        </div>
                    </div>
            }
        </>
    );
}

export default Article;

 

 

<span>{article?.content?.split("\n")?.map(line => <span>{line}<br/></span>)}</span>

 

 

방식은 \n 을 기준으로 문장을 split 하여 배열로 변환한다.

 

그리고 map 함수를 이용하여 <br /> 태그와 함께 뿌려주는 것이다.

 

 

 

목차 돌아가기:

https://binaryjourney.tistory.com/pages/ReactCRUD-create-board-tutorial-v2

 

[React][CRUD] create-board-tutorial-v2

* 인용시 출처 부탁드립니다. 완성 소스 code: github.com/cruellaDev/react-create-board-v2 cruellaDev/react-create-board-v2 updated version of react-create-board. Contribute to cruellaDev/react-create-..

binaryjourney.tistory.com

 

반응형