React Native for Web で Flexbox をデフォルトにする

React Native for Web で全体に Flexbox を適用する Tips
2020.05.04

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

React Native に慣れていると React Native for Web のデフォルトが Flexbox でないことに違和感を覚えるでしょう。書き味を同じようにする設定を紹介します。

なお、 React Native for Web の環境を作る際は次の記事を参考にしてください。

https://dev.classmethod.jp/articles/introduce-react-native-for-web/

追記

公式ドキュメントにやり方が載っていることを教えてもらいました。 HTML ファイルに直でスタイル指定する方法ですね。どの手法ともマッチしそうです。

TL;DR

次の CSS を適用させましょう。

html {
  display: flex;
  height: 100%;
}
body {
  display: flex;
  flex: 1;
}
#root {
  display: flex;
  flex: 1;
}

#root セレクターは React ルートコンポーネントのマウントポイントです。実際の環境に合わせて変更してください。

適用した例は次です。参考にしてください。

https://github.com/januswel/apply-flexbox-globally

実験用のコンポーネント定義

Flexbox 用の最低限のコンポーネント定義です。

import React from 'react';
import { StyleSheet, Text, View } from 'react-native';

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  label: {
    fontSize: 24,
  }
});

export default function App() {
  return (
    <View style={styles.container}>
      <Text style={styles.label}>centerized</Text>
    </View>
  );
}

これを表示すると、横方向はセンタリングされますが、縦方向は画面の一番上となってしまいます。

うまくいっていない例

スタイルを当てる

素直に Flexbox を適用する CSS を当てていきましょう。 htmlbody 、 ルートコンポーネントのマウントポイントそれぞれに display: flex; を指定し、 body とマウントポイントに対して親要素の縦幅いっぱいとするため、 flex: 1; を指定します。

html {
  display: flex;
}
body {
  display: flex;
  flex: 1;
}
#root {
  display: flex;
  flex: 1;
}

ここまでのスタイル指定でも意図通りになっていません。その理由は縦方向の高さが画面の高さとなっていないことです。 html 要素に height を指定しましょう。

html {
  height: 100%;
  display: flex;
}

うまくいきました。

うまくいった例

まとめ

create-react-app を使わない場合、 webpackcss-loader の組み合わせなど、バンドルツールを使いましょう。