진행 중인 프로젝트에서 게시글을 등록하는 코드를 작성하게 되었다. 단순히 <TextArea>
로 구현하기에는 UI가 너무 밋밋한 느낌을 주어 Web Editor를 사용하게 되었다.
이미 리액트에는 web editor
를 쉽게 사용하도록 도와주는 다양한 라이브러리가 존재한다. 그 중에서 Toast UI Editor를 사용해보았다.
설치
yarn add @toast-ui/react-editor
or
npm install @toast-ui/react-editor
컴포넌트 추가
먼저 라이브러리에서 <Editor>
컴포넌트를 불러온다. 다음으로 여러가지 속성들을 활용하여 에디터의 기능을 직접 추가해주기만 하면 된다.
참고로 Toast UI Editor
에서는 에디터를 꾸미기 위한 CSS
코드를 별도로 제공하므로 이를 잘 활용하도록 하자.
import { Editor } from "@toast-ui/react-editor"
import '@toast-ui/editor/dist/toastui-editor.css'; // Editor style
function WebEditor() {
return (
<Editor
ref={editorRef}
initialValue=" " // 초기 설정 텍스트
placeholder="내용을 입력해주세요."
previewStyle="vertical" // 마크다운 모드에서 편집 중인 컨텐츠의 모습을 미리볼 수 있는 프리뷰의 UI 형태 결정
height="500px"
initialEditType="wysiwyg" // 초기 설정 에디팅 모드
useCommandShortcut={false} // 키보드 입력 컨트롤
toolbarItems={[ // 에디터 상단 툴바 옵션
['heading', 'bold', 'italic', 'strike'],
['hr', 'quote'],
['ul', 'ol', 'task', 'indent', 'outdent'],
['table', 'image', 'link'],
['code', 'codeblock'],
]}
/>
)
}
오류
initialValue
속성의 값을 설정하지 않으면, Editor
에 추가한 속성들이 모두 initialValue
가 되어 나타났다. 그래서 initialValue=""
로 초기 설정 텍스트를 빈 문자열로 초기화해주었지만, 여전히 오류는 해결되지 않았다.
이것저것 시도해보다가 방법을 알아냈다. initialValue=" "
로, 공백 하나만 넣어주면 간단하게 해결되는 문제였다..
입력 내용 취득
// HTML 태그 형태로 취득
Editor.prototype.getInstance().getHTML()
// MarkDown 형태로 취득
Editor.prototype.getInstance().getMarkdown()
대부분의 웹 페이지는 사용자가 원하는 카테고리로 쉽게 이동할 수 있도록 도와주는 Header
, 그리고 저작권 정보, 개인정보 처리방침 등을 포함하는 Footer
를 포함하고 있다. Header
는 보통 페이지의 최상단에, Footer
는 페이지의 최하단에 위치한다. 각 태그가 적절한 위치를 차지할 수 있도록 효율적으로 코드를 작성하는 방법을 알아보았다.
구성
먼저 App.js
파일은 다음과 같다.
App.js
const GlobalStyle = createGlobalStyle`
${reset} /*브라우저 기본 세팅 초기화*/
body {
font-family: "Noto Sans Kr", sans-serif;
box-sizing: border-box;
height: 100%;
margin: 0;
}
`
const RootDiv = styled.div`
display: flex;
flex-direction: column;
min-height: 100vh;
padding: 0 140px; // footer 공간 마련
`;
const App = () => {
return (
<>
<GlobalStyle /> // global style 지정
<Nav />
<RootDiv> // page 기본 프레임 구성
<Routes />
</RootDiv>
<Footer />
</>
);
};
export default App;
다음으로 <Routes>
컴포넌트의 최상위 컴포넌트의 flex
속성값을 1로 지정한다.
Router.js
const RouterWrapper = styled.div`
flex: 1;
`;
const Routes = () => {
return (
<RouterWrapper>
<Router>
// ...
</Router>
</RouterWrapper>
);
};
export default Routes;
이렇게 되면 RootDiv
컴포넌트의 min-height
속성값이 100vh
이기 때문에 view-height
를 꽉 채울 정도의 높이값이 RouterWrapper
에 할당된다.
이제 Header
와 Footer
의 최상위 컴포넌트에 적절한 height
값을 부여하면 Header
와 Footer
의 높이를 제외한 공간에 RouterWrapper
의 자식 컴포넌트들이 나타나는 모습을 볼 수 있다.