15
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

styled-componentsのas propとforwardedAsについて整理してみた

Posted at

はじめに

styled-componentsのas propforwardedAsへの理解がふわっとしていたため、この機会に整理してみた。
特にforwardedAsは本家サイトを見ても理解しにくかったので、、、今回ちゃんと整理した。

as propってなに?

v4から追加された機能で、レンダリングする要素のタグを動的に変更できる機能。
styled-componentsでスタイルは使い回して、レンダリングされるタグだけ変更したい場合に利用する。

「ボタンとリンクを別で実装するが、同じスタイルを適用したい」などのユースケースで非常に役立つ。
同じスタイルのコンポーネントを作り分けなくてよくなるのはありがたい。

as propはどうやって書く?

ざっくり書くとこんなかんじ

Hoge = styled.div``;    // .Hoge(div)
Piyo = styled(Hoge)``;  // .Piyo(Hoge + Piyo)(div)
<Piyo as="h1" />      // .Piyo(Hoge + Piyo)(h1)

Hoge = styled.div``;    // .Hoge(div)
Piyo = () => <Hoge />;  // .Piyo(() => <Hoge /> + Piyo)(div)
<Piyo as="h1" />      // .Piyo(() => <Hoge /> + Piyo)(h1)

具体的に書くとこんなかんじ

import styled from "styled-components"
import { Link } from "react-router-dom"

// divなど、汎用的なタグで定義しておくと使い回しやすいかも。
const Base = styled.div`
  color: red;
`;

// divのまま使ってもOK
<Base>Hello World!</Base>

// spanとして定義
<Base as="span">hoge</Base>

// linkとして定義
<Base as={Link} to="home">hoge</Base>

// 継承も可能
const FontBold = styled(Base)`
  font-weight: bold;
`;

<FontBold as="span">hoge</FontBold>
<FontBold as={Link} to="home">hoge</FontBold>

// 継承はこんな書き方もできる
const FontLarge = styled(() => <Base />)`
  font-size: large;
`;

forwardedAsってなに?

v4.3から追加された機能で、styled()as propを渡す場合に利用する機能。
別コンポーネントをラップする場合、forwardedAsを使用してラップされたコンポーネントにas propを渡すことが可能。
※拡張スタイル付きコンポーネントではas propを使用しても親スタイルは継承されない。

forwardedAsはどうやって書く?

import styled from "styled-components"

const Cell = styled.td`
  background-color: ${props => props.bgColor || "blue"};
`;

const StyledCell = styled(Cell)`
  color: red;
`;

const SomeCell = ({ as, ...props}) => {
  return <StyledCell forwardedAs={as} {...props} />;
};

const ExtendedCell = styled(SomeCell)`
  border: 1px solid red;
`;

render(
  <table>
    <tr>
      <ExtendedCell bgColor="orange" forwardedAs="th">
        hoge
      </ExtendedCell>
    </tr>
  </table>
);

まとめ

モヤモヤが少しスッキリした気がする。
あと、複雑なコードを極力書かないで済むような設計にしたいと改めて思った。

15
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?