반응형
다음처럼 DB에 저장된 글이 있다고 해보자.
안녕하세요.
저희 사이트는 https://www.naver.co.kr 입니다
감사합니다.
이것을 react에서 다음과 같은 컴포넌트로 만들었었다.
function viewSplitLine(content) {
return (
<div>
<pre className={"content_pre"}>
{content}
</pre>
</div>
)
}
사용하는 곳
...
return (
{viewSplitLine(content)}
)
...
그런데 pre태그를 쓰면 text를 그대로 보여주게 된다. 그래서 이번에 할 것은 http, https 로 되어있는 것에는 링크로 변경하고 그것을 html로 전환하여 보여주려 한다.
일단 글 중에 http, https 로 있을때 a 태그를 감싸는 것을 먼저 만든다.
const replace = (content) => {
const convertContent = content.replace(urlRegex, function (url) {
return '<a href="' + url + '" target="_blank">' + url + '</a>';
})
}
이렇게 하면 다음처럼 코드가 완성된다.
그럼 이제 글 한줄마다 p 태그로 감싸야 한다. 그러지 않고 html에 노출하면 다음처럼 된다.
이 부분을 추가하기 위해 아래 코드를 추가한다.
..
const replace = (content) => {
const convertContent = content.replace(urlRegex, function (url) {
return '<a href="' + url + '" target="_blank">' + url + '</a>';
})
const htmlArr = [];
convertContent.split('\n').forEach(function (text) {
const textHtml = "<p>" + text + "</p>";
htmlArr.push(textHtml)
})
return htmlArr
}
..
htmlArr 에서 보면 다음처럼 배열로 추가되어 있다.
이제 이걸 html로 랜더링해주면 된다.
일단 글을 그대로 보여주기 위해선 태그로 감싸야하는데, 여기서는 1줄씩 보여주는 것을 p태그로 감쌌다. 그런데 이러다보면 다음과 브라우저에 적용된다
function viewSplitLine(content) {
const urlRegex = /(https?:\/\/[^\s]+)/g;
// 링크를 감지하여 a 태그로 감싸기
const replace = (content) => {
const convertContent = content.replace(urlRegex, function (url) {
return '<a href="' + url + '" target="_blank">' + url + '</a>';
})
const htmlArr = [];
convertContent.split('\n').forEach(function (text) {
const textHtml = "<p>" + text + "</p>";
htmlArr.push(textHtml)
})
return htmlArr
}
return (
<div>
{replace(content)}
</div>
)
}
이때 사용할 수 있는 것이 바로 dangerouslySetInnerHTML 옵션이다. 해당옵션은 브라우저 Dom에 innerHtml을 사용할 수 있게 해준다. 상세 설명은 아래 링크를 참조한다.
https://ko.reactjs.org/docs/dom-elements.html
적용방법은 다음과 같다.
function createMarkup() {
return {__html: 'First · Second'};
}
function MyComponent() {
return <div dangerouslySetInnerHTML={createMarkup()} />;
}
그래서 응용해보면 다음과 같다.
function viewSplitLine(content) {
const urlRegex = /(https?:\/\/[^\s]+)/g;
// 링크를 감지하여 a 태그로 감싸기
const replace = (content) => {
const convertContent = content.replace(urlRegex, function (url) {
return '<a href="' + url + '" target="_blank">' + url + '</a>';
})
const htmlArr = [];
convertContent.split('\n').forEach(function (text) {
const textHtml = "<p>" + text + "</p>";
htmlArr.push(textHtml)
})
// return htmlArr
return {__html: htmlArr};
}
return (
<div>
<div dangerouslySetInnerHTML={replace(content)}></div>
</div>
)
}
그런대 적용해보니 다음처럼 보이지 않던 콤마(,)가 보인다. 배열이다보니 붙은 콤마다. 이것은 join 을 이용해 해결할 수 있다.
변경전: return {__html: htmlArr};
변경후: return {__html: htmlArr.join("")};
이제 잘 나온다.
최종 코딩
function viewSplitLine(content) {
const urlRegex = /(https?:\/\/[^\s]+)/g;
// 링크를 감지하여 a 태그로 감싸기
const replace = (content) => {
const convertContent = content.replace(urlRegex, function (url) {
return '<a href="' + url + '" target="_blank">' + url + '</a>';
})
const htmlArr = [];
convertContent.split('\n').forEach(function (text) {
const textHtml = "<p>" + text + "</p>";
htmlArr.push(textHtml)
})
return {__html: htmlArr.join("")};
}
return (
<div>
<div dangerouslySetInnerHTML={replace(content)}></div>
</div>
)
}
export {viewSplitLine}
끝.
반응형
'공부 > 프로그래밍' 카테고리의 다른 글
[springboot] @EnableResourceServer 사용 중 Using generated security password 가 보일 때 (0) | 2021.05.12 |
---|---|
[aws] MediaConvert + lambda 를 이용해 원하는 화질로 파일 분리하기 (0) | 2021.05.10 |
[aws] cloudfront 에 s3 연결 후 access denied 뜰 때 (0) | 2021.05.05 |
[aws] cloudfront 에 접근제한 및 가능 URL 만들기(Access denied) (0) | 2021.05.03 |
[aws] cloudfront 와 도메인 연결(Alternate Domain Names (CNAMEs))때 주의점 (0) | 2021.04.30 |
댓글