styled-components

2022-11-28 hit count image

react-nativeスタイリングのためstyled-componentsライブラリを活用する方法について説明します。

リアクトネイティブ(React Native)プロジェクト生成

TypeScriptを適用したプロジェクトで進めます。RNへTypeScriptを適用する方法は以前のブログをご参考してください。

styled-componentsライブラリをインストール

styled-componentsライブラリとTypeScriptを連動するためのライブラリをインストールします。

npm install --save styled-components
npm install --save-dev babel-plugin-styled-components @types/styled-components-react-native
  • styled-components: styled-componentsライブラリです。
  • @types/styled-components-react-native: TypeScriptへ必要なstyled-componentsのタイプです。
  • babel-plugin-styled-components: 必須ではないけど、デバッグする時、class名を分かりやすくしてくれます。babel.config.jsへ下記のように設定します。
module.exports = {
  ...
  plugins: ['babel-plugin-styled-components'],
};

TypeScriptがstyled-componentsのタイプを認識できるようにするため、tsconfig.jsonファイルを開いて下記のように修正します。

{
  ...
  "compilerOptions": {
    ...
    "types": ["@types/styled-components-react-native"]
  },
}

ERESOLVE unable to resolve dependency tree

styled-componentsをインストールする時、下記のようなエラーが発生する場合があります。

npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree

この時はReact Nativeプロジェクトフォルダに.npmrcファイルを生成して次のように修正します。

legacy-peer-deps=true

そして、再びstyled-componentsをインストールすると、問題なくインストールされることが確認できます。

使い方

styled-componentsは全般的なスタイルを管理するためthemeの機能を提供してます。themeを使う方法と基本的使い方を説明します。

Class Componentで基本的使い方

  • 基本的なスタイル適用する方法
// src/App.tsx
...
import styled from 'styled-components/native';
...
const Container = styled.View`
  flex: 1;
  justify-content: center;
  align-items: center;
  background-color: #f5fcff;
`;
const MainText = styled.Text`
  font-size: 20px;
  text-align: center;
  margin: 10px;
  color: red;
`;
...
interface Props {}
interface State {}
export default class App extends React.Component<Props, State> {
  render() {
    return (
      <Container>
        <MainText>Hello world</MainText>
      </Container>
    );
  }
}
  • propsを使って動的にスタイルを適用する方法
// src/App.tsx
...
import styled from 'styled-components/native';
...

interface IContainerProps {
  background: string;
}

const Container = styled.View`
  flex: 1;
  justify-content: center;
  align-items: center;
  background-color: ${(props:IContainerProps) => props.background ? props.background : 'white'};
`;
const MainText = styled.Text`
  font-size: 20px;
  text-align: center;
  margin: 10px;
  color: red;
`;
...
interface Props {}
interface State {}
export default class App extends React.Component<Props, State> {
  render() {
    return (
      <Container background="red">
        <MainText>Hello world</MainText>
      </Container>
    );
  }
}

Class ComponentでThemeを使う方法

公式サイトにはTypeScriptを使ってthemeを使う方法が詳しく書いております。

公式サイトと参考サイトを見たらstyled-componentsを使うためには相対パスを使う問題点があります。

それで私たちは公式サイトの方式ではなく、”propsを使って動的にスタイルを適用する方法”を応用して使ってます。

  • src/@types/index.d.tsファイル
// src/@types/index.d.ts
interface ITheme {
  color: {
    white: string;
    black: string;
  };
  fonts: {
    normal: string;
  };
}
  • src/Theme.tsxファイル
// src/Theme.tsx
export default {
  color: {
    white: '#FFFFFF',
    black: '#000000',
  },
  fonts: {
    normal: '14px',
  },
};
  • src/App.tsxファイル
...
// src/App.tsx
import { ThemeProvider } from 'styled-components';
import styled from 'styled-components/native';
import Theme from './Theme';
...

interface IContainerPorps {
  theme?: ITheme;
}

const Container = styled.View`
  flex: 1;
  justify-content: center;
  align-items: center;
  background-color: ${(props:IContainerProps) => props.theme && props.theme.color.black};
`;
const MainText = styled.Text`
  font-size: 20px;
  text-align: center;
  margin: 10px;
  color: red;
`;
...
interface Props {}
interface State {}
export default class App extends React.Component<Props, State> {
  render() {
    return (
      <ThemeProvider theme={Theme}>
        <Container>
          <MainText>Hello world</MainText>
        </Container>
      </ThemeProvider>
    );
  }
}

Function Componentsで基本的使い方

import React from 'react';
import styled from 'styled-components/native';

const Container = styled.View`
  flex: 1;
  justify-content: center;
  align-items: center;
  background-color: #f5fcff;
`;
const MainText = styled.Text`
  font-size: 20px;
  text-align: center;
  margin: 10px;
  color: red;
`;

interface Props {}
const App = ({}: Props) => {
  return (
    <Container>
      <MainText>Hello world</MainText>
    </Container>
  );
};

export default App;

Function ComponentsでThemeを使う方法

import React from 'react';
import styled from 'styled-components/native';
import {ThemeProvider} from 'styled-components';
import Theme from './Theme';

interface StyledProps {
  theme: ITheme;
}
const Container = styled.View`
  flex: 1;
  justify-content: center;
  align-items: center;
  background-color: ${(props: StyledProps) =>
    props.theme && props.theme.color.black};
`;
const MainText = styled.Text`
  font-size: 20px;
  text-align: center;
  margin: 10px;
  color: red;
`;

interface Props {}
const App = ({}: Props) => {
  return (
    <ThemeProvider theme={Theme}>
      <Container>
        <MainText>Hello world</MainText>
      </Container>
    </ThemeProvider>
  );
};

export default App;

参考

私のブログが役に立ちましたか?下にコメントを残してください。それは私にとって大きな大きな力になります!

アプリ広報

今見てるブログを作成たDekuが開発したアプリを使ってみてください。
Dekuが開発したアプリはFlutterで開発されています。

興味がある方はアプリをダウンロードしてアプリを使ってくれると本当に助かります。

Posts