일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- createSlice
- Python
- 테코테코
- C++
- redux-saga
- java
- useDispatch
- 이코테
- 리액트
- Algorithm
- 프로그래머스
- redux-toolkit
- react
- 항해플러스
- 자바
- react-router
- 알고리즘
- SW
- 코딩테스트합격자되기
- sw expert academy
- axios
- 항해99
- 매일메일
- maeil-mail
- json-server
- redux
- Get
- react-redux
- programmers
- JavaScript
- Today
- Total
Binary Journey
[React][CRUD] 게시판 만들기 All in One - (Issue.1) \n 을 <br /> 변경하기 본문
[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 님 덕분에 발견할 수 있었다.
이슈 해결을 위해 아래 사이트를 참고했다.
[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