이전부터 프로젝트에 styled-components를 편하게 잘 사용하고 있기도 했고, 강의도 마침 이 플러그인을 사용하였습니다. 다만 강의는 무지 뒤편에서 이 플러그인을 적용시키는데 저는 아직 거기까지 강의를 보지 않았기 때문에 (-.-) 적용하는데 뭔 문제있겄나.. 하고 넣었다가 엄청 헤맸네요. antd와 styled-components 적용기 시작합니다!
우선 설치를 해야겠죠.
npm i antd styled-components
강의에서는 nav 컴포넌트를 따로 만들지 않았는데 저는 나누고 싶어서 나눴습니다. -.- 왜냐면 layout 컴포넌트는 안에 있는 컴포넌트들의 배치 기능만 하도록 하고 싶었기 때문이죠.
// base
import React from 'react';
import Link from 'next/link';
import styled from 'styled-components'; // (1)
// screen
import { Input, Menu } from 'antd';
// (2)
const SearchButton = styled(Input.Search)`
vertical-align: middle;
& .anticon {
margin: 0;
}
`;
const Nav = () => (
<div>
<Menu mode="horizontal">
<Menu.Item key="home"><Link href="/"><a>리액트버드</a></Link></Menu.Item>
<Menu.Item key="profile"><Link href="/profile"><a>프로필</a></Link></Menu.Item>
<Menu.Item key="mail">
<SearchButton enterButton /> // (3)
</Menu.Item>
</Menu>
</div>
);
export default Nav;
적용 방법 자체는 기존 react 프로젝트에서 적용하는 것과 다를 게 없었습니다.
(1) import로 styled를 불러옵니다.
(2) 해당 dom을 가리키는 변수명을 만들고 일반 태그라면 styled.div``;로 작성하고
antd 컴포넌트일 경우에는 styled.(antdComponent)``;로 작성합니다.
(3) 해당 dom을 변수명으로 변경합니다.
styled component를 작성해서 자동으로 브라우저에서 바뀐 코드가 적용될 때는 적용이 되는데... 새로고침하면 style이 적용이 안되었습니다. 그 때 콘솔에서는 영어로 서버의 class-name과 클라이언트의 class-name이 다르다고 떴습니다.
구글링을 해보니 babel이 리로드가 되지 않아서라고 하네요. 음.. 강의에서는 맨 끝부분의 코드를 봐도 babel.rc가 없었지만 제가 적용이 안되니 어쩌겠어요. babel.rc를 추가했습니다.
{
"presets": [
"next/babel"
],
"plugins": [
[
"styled-components",
{
"ssr": true,
"displayName": true,
"preprocess": false
}
]
]
}
오, 적용은 됐습니다. 그런데 스타일 컴포넌트로 적용한 css는 렌더링 될 때마다 스타일이 적용되는 게 브라우저에 다 보였습니다....
styled-components는 javascript여서 javascript 렌더링 순서에서 렌더링이 되어 유저 눈에 스타일 적용되는 게 다 보였던 겁니다.. 리액트에선 이런 문제 없었는데 -.-...
검색하다 또 찾게된 방법
_document.js를 만들어 아래 내용을 넣는 것입니다.
수업에서는 _app.js만 있고 _document.js가 없는데 원래 index.html 역할을 하는 곳이 _document.js 파일이다보니 _app.js에 있던 것도 옮겨주었습니다.
import Document, {
Html, Head, Main, NextScript,
} from 'next/document';
import { ServerStyleSheet } from 'styled-components';
export default class MyDocument extends Document {
static async getInitialProps(ctx) {
const sheet = new ServerStyleSheet();
const originalRenderPage = ctx.renderPage;
try {
ctx.renderPage = () => originalRenderPage({
enhanceApp: (App) => (props) => sheet.collectStyles(<App {...props} />),
});
const initialProps = await Document.getInitialProps(ctx);
return {
...initialProps,
styles: (
<>
{initialProps.styles}
{sheet.getStyleElement()}
</>
),
};
} finally {
sheet.seal();
}
}
render() {
return (
<Html>
<Head>
<style />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/antd/3.16.2/antd.css" />
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
<title>
은 _document.js에 넣으면 안됩니다. 각 페이지마다 제목이 다를 수도 있고 next.js에서 금하고 있습니다.
감사합니다! 도움많이됐어요!