FAQ

v6に移行するために何をする必要がありますか?

まず、必要なパッケージを最新バージョンに更新することから始めましょう。

NPMを使用している場合

npm install styled-components@^6.0.0 stylis@^4.0.0
npm uninstall @types/styled-components

Yarnを使用している場合

yarn add styled-components@^6.0.0 stylis@^4.0.0
yarn remove @types/styled-components

styled-componentsは独自の型を提供するようになったため、コミュニティの型は必要なくなりました。

TypeScript

TypeScript愛好家にとって朗報です。styled-componentsは、ネイティブでTypeScriptで記述されるようになりました! これまでTypeScriptを使用したことがなくても、不明なプロップを使用している場合や、プロップの値が予想と異なる場合にアラートを出すことができるため、プロジェクトの信頼性を向上させるために推奨されます。

ただし、プロジェクトでTypeScriptを使用していない場合でも、心配はいりません。VS CodeのようなIDEは型を認識し、コードを書くときにヒントを提供します。

shouldForwardPropはデフォルトで提供されなくなりました

スタイリングを一時的なプロップ ($prefix)を使用するように移行していない場合、v6ではスタイリングプロップがDOMに渡されることに関するReactの警告が表示されることに気付くかもしれません。v5の動作を復元するには、StyleSheetManagerを使用します

import isPropValid from '@emotion/is-prop-valid';
import { StyleSheetManager } from 'styled-components';


function MyApp() {
    return (
        <StyleSheetManager shouldForwardProp={shouldForwardProp}>
            {/* other providers or your application's JSX */}
        </StyleSheetManager>
    )
}


// This implements the default behavior from styled-components v5
function shouldForwardProp(propName, target) {
    if (typeof target === "string") {
        // For HTML elements, forward the prop if it is a valid HTML attribute
        return isPropValid(propName);
    }
    // For other elements, forward all props
    return true;
}

ベンダープレフィックスはデフォルトで省略されます

Webとブラウザは2023年までに大幅に成熟したため、ベンダープレフィックスは不要な場合がよくあります。したがって、v6リリースでは、ページに配信されるCSSの量を減らすために、デフォルトで自動プレフィックスを省略することにしました。v5の動作を優先する場合は、StyleSheetManagerを使用して復元できます

import { StyleSheetManager } from 'styled-components';


function MyApp() {
    return (
        <StyleSheetManager enableVendorPrefixes>
            {/* other providers or your application's JSX */}
        </StyleSheetManager>
    )
}

この変更に対応するために、元のdisableVendorPrefixesプロップはenableVendorPrefixesに反転されました。disableVendorPrefixesが設定されている場合は、新しいデフォルトであるため、削除できます。

stylisプラグインの更新

styled-components v6は、新しいstylis v4を使用します。StyleSheetManagerstylisPluginsを提供している場合は、プラグインが最新であることを確認してください。たとえば、stylis-plugin-rtlは、更新されたstylisをサポートするために新しいバージョンをリリースしました。

ネストされた構文の処理

stylis v4のアップグレードにより、ネストされたセレクターの処理方法が変更されました。これはブラウザの動作を正しく反映するようになりました。具体的には、&で始まらない疑似セレクター(例::before)には、アンパサンドが暗黙的に追加されなくなりました。

v5の動作

styled.div`
  :hover { color: red; }
`
// .[classname]:hover { color: red; }


styled.div`
  &:hover { color: red; }
`
// .[classname]:hover { color: red; }

v6の動作

styled.div`
  :hover { color: red; }
`
// .[classname] :hover { color: red; } (equivalent to .[classname] *:hover)


styled.div`
  &:hover { color: red; }
`
// .[classname]:hover { color: red; }

一時的な$asおよび$forwardedAsプロップは削除されました

アプリケーションの順序に関する混乱を減らすために、一時的な$asおよび$forwardedAsプロップを削除しました。代わりに、通常のasおよびforwardedAsプロップを使用してください。

レガシーなwithComponent() APIを削除しました

この変更は長い間待望されていました。withComponent APIはサポートされなくなったため、代わりにasプロップを使用してください。asは、定義時にattrs経由で、または実行時に指定できます

import styled from 'styled-components';


const Button = styled.button`
    background: blue;
    color: white;
`;


const ButtonLink = styled(Button).attrs({ as: 'a' })``;


// These are equivalent, but `ButtonLink` allows for attaching further styling if desired.
<Button as="a" href="https://styled-components.dokyumento.jp">
<ButtonLink href="https://styled-components.dokyumento.jp">

最小限のNodeサポートをv16+に引き上げました

Nodeのメンテナンススケジュールに合わせて、セキュリティパッチをまだ受信している最も古いランタイムとしてv16をサポートするようになりました。

v5に移行するために何をする必要がありますか?

準備はできましたか?

npm install styled-components@^5.0.0 react@^16.8 react-dom@^16.8 react-is@^16.8

React Nativeを使用している場合は、少なくともv0.59(フックをサポートする最初のバージョン)が必要です。

それだけです。 💥


styled-components v5は、公開APIの破壊的な変更を導入せず、以下を追加します

  • パフォーマンスのために調整された、コアスタイルシートエンジンの完全な書き直し

  • 新しいフックベースのコンポーネントモデル

  • StyleSheetManagerに新しいプロップがあります

    • disableCSSOMInjection
    • disableVendorPrefixes
    • stylisPlugins
      • bidiのニーズに対応するには、stylis-plugin-rtlでお試しください!

注:v4で非推奨になったサブ関数オブジェクトフォーム.attrs({ prop: props => {} })構文は、v5で削除されます。代わりに関数形式のattrs .attrs(props => ({}))を使用してください(事前にこの更新を行うようにコンソール警告が表示されていたはずです。)

詳細については、公式発表投稿を確認し、v5の内容について学んでください!

jestユーザー向け

jest-styled-components v7にアップデートしてください

npm install jest-styled-components@^7.0.0

cssの@importcreateGlobalStyleに関する注意

現時点では、ブラウザがCSSOM APIを介して@importを処理する方法にいくつかの問題があるため、cGS内で@importを使用することはお勧めしません。代わりに、これらの記述は、通常の<style>タグ内に、コアのindex.htmlファイル(生成されたものまたは静的なもの)に配置するのが最適です。

v4に移行するために何をする必要がありますか?

これは、内部とAPIレベルの両方で多くの変更を含む、非常に大きなリリースです。ベータ版が進むにつれて、以下の項目をより簡単にするためのコードモッドをリリースする予定です。また、以下の手順で問題が見つかった場合は、建設的なフィードバックをお寄せください

  1. 最新のstyled-componentsにアップグレードします
npm install styled-components@^4.0.0
  1. アプリケーションがreact >= 16.3を使用していることを確認してください。内部的には、新しいReact.forwardRef APIと、古いReactバージョンのサポートのためにポリフィルを試したい場合は、新しいコンテキストAPIを使用しています。
npm install react@^16.3 react-dom@^16.3

enzymereact-test-rendererのような他の依存関係を使用している場合、古いバージョンのreactから移行する場合は、完了する関連のアップグレードがさらに必要になる可能性があります。

  1. .extend APIを使用している場合は、代わりにコンポーネントをstyled(StyledComponent)を使用するように切り替えてください。

これを迅速化するためのcodemodが利用可能です

🚫

import styled from 'styled-components'


const Component = styled.div`
  background: blue;
  color: red;
`


const ExtendedComponent = Component.extend`
  color: green;
`

import styled from 'styled-components'


const Component = styled.div`
  background: blue;
  color: red;
`


const ExtendedComponent = styled(Component)`
  color: green;
`

詳細については、「スタイルの拡張」ドキュメントを参照してください。

  1. ページにグローバルスタイルを追加するためにinjectGlobal APIを使用していた場合は、代わりに新しいcreateGlobalStyleヘルパーコンポーネントを使用してください。

これを迅速化するためのcodemodが利用可能です

🚫

import { injectGlobal } from 'styled-components'


injectGlobal`
  body {
    color: red;
  }
`

import { createGlobalStyle } from "styled-components"


const GlobalStyle = createGlobalStyle`
  body {
    color: red;
  }
`


// later in your app's render method
<React.Fragment>
  <Navigation />
  <OtherImportantTopLevelComponentStuff />
  <GlobalStyle />
</React.Fragment>

createGlobalStyleのドキュメントを参照して、injectGlobalでは以前は不可能だった、それを使ってできるクールなことをすべて確認してください!

  1. innerRefプロップを使用していた場合は、通常のrefに変更してください。

🚫

const Component = styled.div`
  background: blue;
  color: red;
`


// later in your render method
<Component innerRef={element => { this.myElement = element }}>Something something</Component>

const Component = styled.div`
  background: blue;
  color: red;
`


// later in your render method
<Component ref={element => { this.myElement = element }}>Something something</Component>
  1. cssヘルパーなしで、部分的にkeyframesコンポーネントを使用している場合は、今すぐヘルパーを使用する必要があります。一般に、スタイル付きコンポーネントに補間されるスタイリング部分を構成する場合は、常にcssヘルパーを使用してください。

🚫

import styled, { keyframes } from 'styled-components'


const animation = keyframes`
  0% {
    opacity: 0;
  }


  100 {
    opacity: 1;
  }
`


const animationRule = `
  ${animation} 1s infinite alternate
`


const Component = styled.div`
  animation: ${animationRule};
`

import styled, { css, keyframes } from 'styled-components'


const animation = keyframes`
  0% {
    opacity: 0;
  }


  100 {
    opacity: 1;
  }
`


const animationRule = css`
  ${animation} 1s infinite alternate;
`


const Component = styled.div`
  animation: ${animationRule};
`
  1. attrs({})を使用していて、そこに渡す属性の一部が関数の場合は、より簡単で強力な構成のために、代わりに新しいattrs(props => ({}))構文に切り替えることをお勧めします。

🚫

import styled from 'styled-components'


const Input = styled.input.attrs({
  type: props => props.inputType,
})`
  background: blue;
  color: red;
`

import styled from 'styled-components'


const Input = styled.input.attrs(props => ({
  type: props.inputType,
}))`
  background: blue;
  color: red;
`
  1. TypeScriptを使用している場合は、型定義がDefinitelyTypedに配置されるようになりました
npm install @types/styled-components

以上です!移行とは別に、将来的にはwithComponent APIを置き換えることを目的とした、新しい"as" プロップをよく読むことを強くお勧めします。

ルールをネストできますか?

はい。ネストは、Sassから意図的に移植された機能です。控えめに使用すると、すべての要素に明示的なクラスを作成する必要性を減らすことで、コードを軽量化する優れた方法になります。

また、親コンポーネントは、影響を受ける子コンポーネントの適切な関心事ではないコンテキスト制約を定義するために使用できます。

First
Second
Third
First
Second
Third

また、メディアクエリを配置するのに非常に便利です。コンポーネントが任意の解像度でどのように応答するかを一目で確認できるからです。

Hello world!

CSSフレームワークを使用できますか?

既存のCSSフレームワークをstyled-componentsと統合するのは非常に簡単です!既存のクラス名をコンポーネントとともに使用できます。

たとえば、.small.bigの2つのクラスを再利用したい既存のアプリがあるとします。クラスを常にコンポーネントにアタッチする場合は、attrsメソッドを使用してアタッチする必要があります。一部の場合にのみアタッチする場合は、常に使用しているようにclassNameプロップを使用できます!

フレームワークにページに含める必要のある生のグローバルCSSが多数ある場合は、createGlobalStyle APIを使用して追加できます。これは、CSSリセットのようなものにも役立ちます。

styled-components v3以下では、グローバルスタイルの以前のAPIはinjectGlobalであったことに注意してください。

より高い特異性でスタイルをオーバーライドするにはどうすればよいですか?

特異性の高いスタイルでスタイルをオーバーライドする方法は、単に自分のスタイルの特異性を高めることです。これは!importantを使用して行うことができますが、それはエラーが発生しやすく、一般的に良い考えではありません。

次の手法をお勧めします

const MyStyledComponent = styled(AlreadyStyledComponent)`
  &&& {
    color: #BF4F74;
    font-weight: bold;
  }
`

&は生成されたクラスに置き換えられるため、挿入されたCSSは次のようになります。

.MyStyledComponent-asdf123.MyStyledComponent-asdf123.MyStyledComponent-asdf123 {
  color: #BF4F74;
  font-weight: bold;
}

繰り返しクラスは、記述するのが非常に面倒であることなく、ソースの順序をオーバーライドするのに十分な高さまで特異性を高めます!

インラインスタイルをオーバーライドするにはどうすればよいですか?

インラインスタイルは常に外部CSSよりも優先されるため、特異性を高めるだけではオーバーライドできません。

ただし、!importantと組み合わせて、スタイルelement-attr CSSセレクターを使用するという優れたトリックがあります。

const MyStyledComponent = styled(InlineStyledComponent)`
  &[style] {
    font-size: 12px !important;
    color: blue !important;
  }
`

DOMノードに2つのクラスがあるのはなぜですか?

実際には、各ノードには2つのクラスが接続されています。1つはコンポーネントごとに静的です。つまり、スタイル付きコンポーネントの各要素にはこのクラスがあります。これにはスタイルがアタッチされていません。代わりに、DOMオブジェクトがどのスタイル付きコンポーネントに属しているかをすばやく識別したり、DevToolsでマイナーな変更を加えたりするために使用されます。また、コンポーネントセレクターにも使用されます。静的クラスは、おそらく.sc-fVOeaWのように見えるでしょう。

もう1つは動的です。つまり、挿入結果に基づいて、異なるプロップを持つスタイル付きコンポーネントのすべての要素で異なります。おそらく.fVOeaWのように見えるでしょう(「sc」プレフィックスがないことに注意してください)。

たとえば、スタイル付きコンポーネント<Button />は毎回同じ静的クラスでレンダリングされます。スタイルが<Button secondary />のように補間を使用して変更された場合、静的クラスは同じままである一方で、動的クラスは異なるものになります。

attrsを使用する場合

attrsを使用して、スタイル付きコンポーネントに属性を渡すことができますが、そうすることが常に賢明であるとは限りません。

経験則として、スタイル付きコンポーネントのすべてのインスタンスにそのプロップを持たせたい場合はattrsを使用し、すべてのインスタンスに異なるプロップが必要な場合はプロップを直接渡します

const PasswordInput = styled.input.attrs(props => ({
  // Every <PasswordInput /> should be type="password"
  type: "password"
}))``


// This specific one is hidden, so let's set aria-hidden
<PasswordInput aria-hidden="true" />

他のプロップの「モード」に基づいて推測できるプロップについても同様です。この場合、attrsのプロパティを、他のプロップに基づいてそのプロップを計算する関数に設定できます。

私はライブラリの作者です。自分のライブラリにstyled-componentsをバンドルすべきでしょうか?

もしあなたがライブラリの作者であれば、styled-componentsモジュールをライブラリにバンドルして配布することは推奨しません。これを実現するには、以下の2つのステップが必要です。

  • パッケージの依存関係でstyled-componentsを外部化としてマークする
  • ライブラリのバンドルからstyled-componentsを削除する

パッケージの依存関係でstyled-componentsを外部化としてマークする

これを行うには、dependenciesからdevDependenciesに移動し、peerDependenciesリストにあなたのpackage.jsonファイルに含める必要があります。

{
-   "dependencies" : {
+   "devDependencies" : {
      "styled-components": "^3.4.9"
    },
+   "peerDependencies" : {
+     "styled-components": ">= 3"
+   }
  }

styled-componentsdevDependenciesに移動することで、ライブラリと一緒にインストールされないことが保証されます(npm installまたはyarn addはライブラリがインストールされる際にdevDependenciesを無視します)。

styled-componentspeerDependenciesに追加すると、ライブラリの利用者にstyled-componentsがライブラリに含まれておらず、自身でインストールする必要があることを知らせます。

また、peerDependenciesセクションでは、バージョン文字列がより許容範囲の広い>= 3になっていることに注意してください。これにより、styled-componentsの将来のバージョンが自動的に動作するようになり、破壊的な変更が最終的に追加された場合にのみ、ライブラリへのパッチ更新で範囲を狭めることができます。

ライブラリのバンドルからstyled-componentsを削除する

ライブラリを配布する前にバンドルしている場合は、styled-componentsを一緒にバンドルしていないことを確認してください。以下に、いくつかの一般的なモジュールバンドルツールでこれを行う方法の例を示します。

Microbundleの場合

Microbundleを使用している場合、このステップは自動的に処理されます。Microbundleは、peerDependenciesリスト内のすべての依存関係を外部として扱い、ビルドから除外します。

Rollup.jsの場合

Rollup.jsを使用している場合は、設定でexternalオプションを指定する必要があります。

export default {
    entry: "my-awesome-library.js",
+   external: [
+     "styled-components"
+   ]
  }

別の方法としては、rollup-plugin-peer-deps-externalプラグインを使用すると、peerDependenciesexternalオプションの配列に自動的に追加できます。

+ import peerDepsExternal from 'rollup-plugin-peer-deps-external';

  export default {
    entry: "my-awesome-library.js",
+   plugins: [
+    // Preferably set as first plugin.
+    peerDepsExternal(),
+   ]
  }

Webpackの場合

Webpackを使用している場合は、設定でexternalsオプションを指定する必要があります。

modules.export = {
    entry: "my-awesome-library.js",
+   externals: {
+     "styled-components": {
+       commonjs: "styled-components",
+       commonjs2: "styled-components",
+       amd: "styled-components",
+     },
+   },
  }

Webpackでライブラリをバンドルする方法に関するより詳しい情報は、Webpackドキュメントの「ライブラリの作成」セクションにあります。

なぜページ上で複数のモジュールインスタンスに関する警告が表示されるのですか?

以下のような警告メッセージがコンソールに表示される場合、ページで複数のstyled-componentsインスタンスが初期化されている可能性があります。

It looks like there are several instances of "styled-components" initialized in this application. This may cause dynamic styles not rendering properly, errors happening during rehydration process and makes you application bigger without a good reason.


If you are using a building tool like webpack, consider checking your bundle for duplication of the "styled-components" module.

これは、動的なスタイルが正しく動作しない、またはサーバーサイドレンダリングを使用している場合にリハイドレーション中にエラーが発生する可能性があります。

考えられる理由

これが発生する一般的な理由がいくつかあります。

  • 同じページで実行されている複数のアプリケーションでstyled-componentsを使用している(例:Webpackの複数のエントリポイントが同じページにロードされている)
  • 依存関係のどこかに別のstyled-componentsライブラリがある
  • プロジェクトにモノレポ構造(例:lerna、yarn workspaces)があり、複数のパッケージでstyled-componentsモジュールが依存関係になっている(これは多かれ少なかれ前のものと同じです)

1つのページで複数のアプリケーションを実行する

1つのページで複数のアプリケーションを実行している場合は、すべてのアプリケーションで1つのstyled-componentsモジュールを使用することを検討してください。Webpackを使用している場合は、CommonsChunkPluginを使用して、styled-componentsモジュールを含む明示的なベンダーチャンクを作成できます。

module.exports = {
    entry: {
+     vendor: ["styled-components"],
      app1: "./src/app.1.js",
      app2: "./src/app.2.js",
    },
    plugins: [
+     new webpack.optimize.CommonsChunkPlugin({
+       name: "vendor",
+       minChunks: Infinity,
+     }),
    ]
  }

node_modules内の重複したモジュール

問題が依存関係のどこかにある重複したstyled-componentsモジュールにあると思われる場合は、これをチェックする方法がいくつかあります。npm ls styled-componentsyarn list --pattern styled-components、またはアプリケーションフォルダでfind -L ./node_modules | grep /styled-components/package.jsonコマンドを使用できます。

これらのコマンドで重複が特定されなかった場合は、styled-componentsの複数のインスタンスについてバンドルを分析してみてください。バンドルソースを確認するか、source-map-explorerwebpack-bundle-analyzerなどのツールを使用できます。

重複が問題の原因であると特定した場合、それを解決するために試すことができることがいくつかあります。

npmを使用している場合は、npm dedupeを実行してみてください。このコマンドはローカル依存関係を検索し、共通の依存関係をツリーの上位に移動することで構造を単純化しようとします。

npm dedupeはシンボリックリンクされたフォルダ(つまり、npm linkを使用する場合)ではうまく機能しないことに注意してください。

Webpackを使用している場合は、styled-componentsモジュールを解決する方法を変更できます。Webpackが依存関係を探すデフォルトの順序を上書きし、アプリケーションのnode_modulesをデフォルトのノードモジュール解決順序よりも優先させることができます。

resolve: {
+   alias: {
+     "styled-components": path.resolve(appFolder, "node_modules", "styled-components"),
+   }
  }

Lernaでの使用

Lernaモノレポでパッケージ間でstyled-componentsを実行するための1つの可能な修正は、共有の依存関係をモノレポファイルのルートにホイストすることです。--hoistフラグを使用してブートストラップオプションを実行してみてください。

lerna bootstrap --hoist

または、package.jsonファイルからstyled-componentsを削除し、最上位のpackage.jsonファイルに手動でホイストすることもできます。

Lernaルートフォルダのpackage.jsonファイルの例

{
  "name": "my-styled-monorepo",
  "devDependencies": {
    "lerna": "3.6.0"
  },
  "dependencies": {
    "styled-components": "3.4.5"
  },
  "scripts": {
    "bootstrap": "lerna bootstrap",
    "clean": "lerna clean",
    "start": "lerna run start",
    "build": "lerna run build"
  }
}

なぜ、renderメソッド内でstyled-componentsを宣言することを避けるべきなのですか?

Reactコンポーネントのrenderメソッド内でstyled componentを宣言すると、レンダリングのたびに新しいコンポーネントが動的に作成されます。これは、Reactが、その後のレンダリングごとに、変更された部分の差分を計算する代わりに、DOMサブツリーのその部分を破棄して再計算する必要があることを意味します。これにより、パフォーマンスのボトルネックや予期しない動作が発生します。

🚫

const Header = () => {
  const Title = styled.h1`
    font-size: 10px;
  `


  return (
    <div>
      <Title />
    </div>
  )
}

const Title = styled.h1`
  font-size: 10px;
`


const Header = () => {
  return (
    <div>
      <Title />
    </div>
  )
}

なぜHTML属性に関する警告が表示されるのですか?

以下の警告メッセージは、<div><a> などのHTML DOM要素に非標準の属性がアタッチされていることを示しています。この警告メッセージが表示される場合、あなたまたはあなたが使用しているライブラリが、propsをHTML DOM要素の属性としてアタッチしている可能性があります。

Warning: Received "true" for a non-boolean attribute

この警告が表示される場合は、おそらく"true"が適切な箇所にtrueを渡しています。これは、.attrsプロパティから、またはstyled(Component)コンポーネントに渡している全く関係のないpropから発生している可能性があります。

propsの渡し方について詳しくは、こちらのセクションをご覧ください。

例:

const Link = props => (
  <a {...props} className={props.className}>
    {props.text}
  </a>
)


const StyledComp = styled(Link)`
  color: ${props => (props.red ? 'red' : 'blue')};
`


<StyledComp text="Click" href="https://www.styled-components.com/" red />

これは以下のようにレンダリングされます。

<a text="Click" href="https://www.styled-components.com/" red="true" class="[generated class]">Click</a>

Reactは、<a>要素にとって有効なHTML属性ではない「red」や「text」などの非標準の属性がアタッチされている場合に警告します。

これを修正するには、一時的なpropsを使用するか、propsを分割代入します。

一時的なprops (5.1以降)

これを修正するには、一時的なpropsを使用できます。

const Link = ({ className, text, ...props }) => (
  <a {...props} className={className}>
    {text}
  </a>
)


const StyledComp = styled(Link)`
  color: ${props => (props.$red ? 'red' : 'blue')};
`


<StyledComp text="Click" href="https://www.styled-components.com/" $red />

propsの分割代入

バージョン5.1未満を使用している場合、または一時的なpropsを使用できない場合は、引数分割代入を使用して、既知のスタイリングpropsを取り出すことができます。

const Link = ({ className, red, text, ...props }) => (
  <a {...props} className={className}>
    {text}
  </a>
)


const StyledComp = styled(Link)`
  color: ${props => (props.red ? 'red' : 'blue')};
`


<StyledComp text="Click" href="https://www.styled-components.com/" red />

これは以下のようにレンダリングされます。

<a href="https://www.styled-components.com/" class="[generated class]">Click</a>

引数分割代入を使用すると、propsオブジェクトから取り出された変数は、残りのpropsをスプレッド適用する(...props)際に含まれません。

どのブラウザがサポートされていますか?

styled-componentsは、現在のReactバージョンと同じブラウザセットをサポートしています。

  • v2.x (React v0.14+): IE9以上、すべてのエバーグリーンブラウザ
  • v3.x (React v0.14+): IE9以上、すべてのエバーグリーンブラウザ
  • v4.x (React v16.3+): IE11、IE 9+ (Map + Setポリフィルを使用)、すべてのエバーグリーンブラウザ
  • v5.x (React v16.3+): IE11、すべてのエバーグリーンブラウザ

エバーグリーンブラウザには、オペレーティングシステムのバージョンに関係なく更新できるChromeとFirefox(および派生物)が含まれます。EdgeとSafariも、ここ数年のすべてのバージョンが関連するAPIをサポートしているため、問題なく動作するはずです。

create-react-appでstyled-componentsを使用するにはどうすればよいですか?

ライブラリの基本機能は、他のライブラリと同様にすぐに使用できます。

ただし、サーバーサイドレンダリングを行う場合や、styled-components babelプラグインの高度な機能の一部を利用したい場合は、イジェクトせずに、react-app-rewiredreact-app-rewire-styled-componentsをセットアップする必要があります。

npm linkまたはyarn linkを使用しているときに発生する問題を解決するにはどうすればよいですか?

ローカルリンクは、プロジェクトを同時に共同開発するのに便利なツールです。ただし、reactやstyled-componentsのようにシングルトンとして使用することを意図したライブラリでは、各ローカルプロジェクトがダウンロードされた開発依存関係の完全なセットを持っている可能性が高いため(バンドラーはデフォルトで依存関係のローカルバージョンを優先します)、混乱した状況が生じます。

解決策はエイリアスを追加することです。以下はwebpackの構成例です。

// const path = require('path');


{
  resolve: {
    alias: {
      // adjust this path as needed depending on where your webpack config is
      'styled-components': path.resolve('../node_modules/styled-components')
    }
  }
}

これにより、シンボリックリンクされたプロジェクト間でも、ビルドで常に同じライブラリのコピーが使用されるようになります。

SSRシナリオでのリンク。

リンクされたコンポーネントを持つプロジェクトでcollectStyles関数を使用すると、複雑なシナリオに陥ります。基本的に、何が起こっているかというと、v4の新しい静的コンテキストAPIにより、異なるstyled-componentモジュールがレンダリングするstyled-componentsの独自のリストを管理するようになったため、ホストアプリから見ると、そのスコープ内でstyledコンポーネントが作成されていないため、抽出するものがないように見えます。それらはリンクされたパッケージスコープから作成されました。

どうすれば解決できますか?

1つの解決策は、styled-componentsモジュールパスの解決を常に「ホスト」アプリケーションを指すようにエイリアスを追加することです。ありがたいことに、それを行うためのライブラリが多数あります。この例ではmodule-aliasを使用します。SSRインデックスファイルの先頭に次を追加します。

const path = require('path');
const moduleAlias = require('module-alias');


moduleAlias.addAlias('styled-components', path.join(__dirname, '../node_modules/styled-components'));

これにより、ノードはstyled-componentsのすべてのimport/requireを__dirname, '../node_modules/styled-components'に解決するように指示します。

サーバーサイドレンダリング後のテキストのちらつきを修正するにはどうすればよいですか?

createGlobalStyleや以前のinjectGlobalのようなグローバルスタイリングAPIを使用する場合、@font-face定義などの特定のスタイルをDOMに追加および削除すると、ページ上のテキストが一時的にちらつく可能性があります。これは通常、サーバーサイドレンダリングのリハイドレーションフェーズ中に発生します。この問題を長期的に回避するために、これらの動作のしくみをまだ調整しています。

ただし、font-display CSSルールでこの問題に対するCSSソリューションがあります。ルールを「フォールバック」モードに設定すると、フォントが一度読み込まれると、再読み込みされません。これにより、ちらつきが解消されます。

@font-face {
  font-family: 'Foo';
  src: url('/path/to/foo.woff') format('woff');
  font-style: normal;
  font-weight: 400;
  font-display: fallback; /* <- this can be added to each @font-face definition */
}

styled-components/nativeの宣言がありませんか?

次のエラーメッセージが表示される場合

Could not find a declaration file for module 'styled-components/native'

TypeScriptを使用するReact Nativeプロジェクトでは、@types/styled-components-react-nativeを追加する必要があるためです。