11.
スタイルコンポーネント
スタイルコンポーネント
styled
スタイルコンポーネント名を変数にして設定します。CSSスタイルの設定は `(バッククォーテーション)で囲み、行末は ;(セミコロン) とします。
const スタイルコンポーネント名 = styled `
CSSスタイル設定
`;
styled()
アイコンなどを設定する styled() も用意されています。
const スタイルコンポーネント名 = styled(値) `
CSSスタイル設定
`;
コンポーネントを定義
「styled-components」と「material-ui」でコンポーネントを作成します。
styled-components のインポート
「import styled」で「styled-components」をインポート構文が自動入力できます。

SideMenu.js
import styled from "styled-components"
スタイルコンポーネント作成
「SideMenu.js」のメインコンポーネントの外にスタイルコンポーネントを作成します。

「Container」コンポーネント
コンポーネント「Container」を定義し、「div」のスタイルを空欄で設定します。
...
export default SideMenu
const Container = styled.div ``;
「Header」「Icons」コンポーネント
同様に「Header」「Icons」コンポーネントも定義します。
SideMenu.js
const Container = styled.div ``;
const Header = styled.div ``;
const Icons = styled.div``;
アイコン
styled(Avataer)を入力するとアバターアイコンが設定できます。同時に「material-ui」も自動インポートしてくれます。
//自動で挿入される
import { Avatar } from "@material-ui/core"
...
//styled(Avatar)を定義
const UserAvatar = styled(Avatar) ``;
アバターアイコンの追加
UserAvatarにAvatarを定義し、スタイルも設定しておきます。
SideMenu.js
import { Avatar } from "@material-ui/core"
import styled from "styled-components"
function SideMenu() {
return (
<div>
<h2>Side Menu</h2>
</div>
)
}
export default SideMenu
const Container = styled.div ``;
const Header = styled.div ``;
const UserAvatar = styled(Avatar) `
cursor: pointer;
:hover {
opacity: 0.8;
}
`;
コンポーネントの利用
「SideMenu」コンポーネントからdivタグを削除し、「Container」「Header」「UserAvatar」などのコンポーネントを追加します。
SideMenu.js
...
function SideMenu() {
return (
<Container>
<Header>
<UserAvatar />
<Icons>
</Icons>
</Header>
</Container>
)
}
...
アバターアイコンの確認
ブラウザでアバターアイコンを確認してみましょう。
アイコンの表示
「material-icons」のいくつかのアイコンを表示してみます。
ChatIcon
モジュールインポート
「import」を入力します。
importが入力できました。
SildeMenu.js
import moduleName from 'module'
アイコンの設定
続けて「@material-icons/icons/Chat」をインポートします。

モジュール名は「ChatIcon」とします。
SildeMenu.js
import ChatIcon from '@material-ui/icons/Chat';
MoreVertIcon
同様に「MoreVertIcon」アイコンもインポートしておきます。
SildeMenu.js
import MoreVertIcon from '@material-ui/icons/MoreVert'
アイコンボタンのインポート
「material-ui/core」のインポートで「IconButton」を追記します。
SildeMenu.js
import { Avatar, IconButton } from "@material-ui/core"
アイコンコンポーネントの追加
「Icons」タグに「IconButton」「MoreVertIcon」などのアイコンコンポーネントを追加します。
function SideMenu() {
return (
<Container>
<Header>
<UserAvatar />
<Icons>
<IconButton>
<ChatIcon />
</IconButton>
<MoreVertIcon />
</Icons>
</Header>
</Container>
)
}
Header コンポーネントのスタイル修正
「Header」コンポーネントのスタイルを修正します。
const Header = styled.div`
display: flex;
position: sticky;
top: 0;
background: white;
z-index: 1;
justify-content: space-between;
padding: 15px;
height: 80px;
border-bottom: 1px solid whitesmoke;
`;
アイコンの確認
「ChatIcon」や「MoreVertIcon」などのアイコンが表示されるか確認してみましょう。

リロードでスタイルが反映されない場合
「styled-components」がリロードで反映されないことがあるので「pages/_document.js」に以下のように追記します。「pages/_document.js」がない場合は新規作成します。
pages/_document.js
import Document, { DocumentContext } 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();
}
}
}
_documet.jsとは
「_documet.js」はデフォルトのHTML表示処理を拡張するための機能です。htmlタグやbodyタグをカスタマイズすることができます。
import { Html, Head, Main, NextScript } from 'next/document'
export default function Document() {
return (
<Html>
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
SSRの設定
スタイルコンポーネントをSSR(サーバーサイドレンダリング)するとエラーになることがあります。
Warning: Prop `className` did not match. when using styled components with semantic-ui-react
.babelrcの設定
「.babelrc」ファイルを追加し、「styled-components」のSSRを「true」にします。
{
"presets": ["next/babel"],
"plugins": [["styled-components", { "ssr": true }]]
}