Skip to content

React NativeのViewPropTypes警告の解決方法

問題

React Native 0.68以降のバージョンを使用している場合、以下のような警告が表示されることがあります:

ViewPropTypes will be removed from React Native. Migrate to ViewPropTypes exported from 'deprecated-react-native-prop-types'

この警告は、あなた自身のコードでViewPropTypesを直接使用していなくても、使用しているサードパーティライブラリ(例:react-native-modalnative-basereact-native-snap-carouselなど)が内部的にViewPropTypesに依存している場合に発生します。

原因

React Nativeのバージョン0.68以降、PropTypes関連のメソッドは非推奨となり、将来的に削除される予定です。そのため、これらのメソッドはエラーをスローするように変更されました:

javascript
get ViewPropTypes(): $FlowFixMe {
  invariant(
    false,
    "ViewPropTypes has been removed from React Native. Migrate to " +
      "ViewPropTypes exported from 'deprecated-react-native-prop-types'.",
  );
}

解決方法

以下に、この問題を解決するための複数の方法を紹介します。最も推奨される方法から順に説明します。

方法1: ベストプラクティス - モジュールリゾルバーの使用

この方法は、React Nativeの公式Issuesで議論されているアプローチに基づいており、最も安全でメンテナンス性の高い解決策です。

bash
npm install --save-dev babel-plugin-module-resolver deprecated-react-native-prop-types
bash
yarn add --dev babel-plugin-module-resolver deprecated-react-native-prop-types
  1. プロジェクトのルートにresolver/react-native/index.jsファイルを作成
javascript
import * as StandardModule from "react-native";

const deprecatedProps = {
  ImagePropTypes: require("deprecated-react-native-prop-types/DeprecatedImagePropType"),
  TextPropTypes: require("deprecated-react-native-prop-types/DeprecatedTextPropTypes"),
  ViewPropTypes: require("deprecated-react-native-prop-types/DeprecatedViewPropTypes"),
  ColorPropType: require("deprecated-react-native-prop-types/DeprecatedColorPropType"),
  EdgeInsetsPropType: require("deprecated-react-native-prop-types/DeprecatedEdgeInsetsPropType"),
  PointPropType: require("deprecated-react-native-prop-types/DeprecatedPointPropType"),
};

const imgProx = new Proxy(StandardModule.Image, {
  get(_, prop) {
    if (prop === "propTypes") return deprecatedProps.ImagePropTypes;
    return Reflect.get(...arguments);
  },
});

const txtProx = new Proxy(StandardModule.Text, {
  get(_, prop) {
    if (prop === "propTypes") return deprecatedProps.TextPropTypes;
    return Reflect.get(...arguments);
  },
});

const objProx = new Proxy(StandardModule, {
  get(_, prop) {
    if (prop in deprecatedProps) {
      return deprecatedProps[prop];
    }
    if (prop === "Image") {
      return imgProx;
    }
    if (prop === "Text") {
      return txtProx;
    }
    return Reflect.get(...arguments);
  },
});

module.exports = objProx;
  1. babel.config.jsを設定
javascript
var path = require('path');

module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
  plugins: [
    ["module-resolver", {
      "root": ["."],
      resolvePath(sourcePath, currentFile, opts) {
        if (
          sourcePath === 'react-native' &&
          !(
            currentFile.includes('node_modules/react-native/') ||
            currentFile.includes('node_modules\\react-native\\')
          ) &&
          !(
            currentFile.includes('resolver/react-native/') ||
            currentFile.includes('resolver\\react-native\\')
          )
        ) {
          return path.resolve(__dirname, 'resolver/react-native');
        }
        return undefined;
      }
    }],
  ],
};
  1. キャッシュをクリアして再起動
bash
expo r -c
bash
npm start -- --reset-cache

方法2: パッチパッケージを使用した修正

一時的な解決策として、直接React Nativeのコードを修正する方法もありますが、React Nativeをアップデートするたびに再適用する必要があります。

bash
npm install patch-package deprecated-react-native-prop-types

node_modules/react-native/index.jsを開き、以下のセクションを修正します:

javascript
// 修正前:
get ViewPropTypes(): $FlowFixMe {
  invariant(
    false,
    "ViewPropTypes has been removed from React Native. Migrate to " +
      "ViewPropTypes exported from 'deprecated-react-native-prop-types'.",
  );
}

// 修正後:
get ViewPropTypes(): $FlowFixMe {
  return require("deprecated-react-native-prop-types").ViewPropTypes;
}

修正後、パッチを作成します:

bash
npx patch-package react-native

方法3: サードパーティライブラリの修正

警告の原因となっている特定のライブラリを直接修正する方法です。例えば、react-native-snap-carouselが原因の場合:

  1. node_modules/react-native-snap-carousel/以下の該当ファイルを開く
  2. ViewPropTypesのインポートを修正:
javascript
// 修正前:
import { ViewPropTypes } from 'react-native';

// 修正後:
import { ViewPropTypes } from 'deprecated-react-native-prop-types';
  1. パッチを作成:
bash
npx patch-package react-native-snap-carousel

方法4: 警告を無視する(一時的な対策)

本質的な解決ではありませんが、開発中に警告を非表示にしたい場合:

javascript
import { LogBox } from "react-native";

if (__DEV__) {
  const ignoreWarns = [
    "ViewPropTypes will be removed from React Native",
    "exported from 'deprecated-react-native-prop-types'.",
  ];

  LogBox.ignoreLogs(ignoreWarns);
}

WARNING

この方法は警告を隠すだけで、根本的な解決にはなりません。プロダクション環境では推奨されません。

推奨される長期的な解決策

  1. ライブラリの更新: ViewPropTypesを使用しているサードパーティライブラリの最新バージョンがないか確認する
  2. TypeScriptへの移行: PropTypesの代わりにTypeScriptを使用することを検討する
  3. 代替ライブラリの検討: メンテナンスが活発なライブラリに置き換える

よくある質問

Q: 自分はViewPropTypesを使っていないのに、なぜ警告が表示されるのですか? A: 使用しているサードパーティライブラリが内部的にViewPropTypesに依存しているためです。

Q: どのライブラリが原因か特定するには? A: 警告スタックトレースを確認するか、以下のコマンドで検索できます:

bash
grep -r "ViewPropTypes" node_modules/

Q: この修正はReact Nativeのアップデート後も持続しますか? A: 方法1(モジュールリゾルバー)を使用するか、パッチパッケージを適用している限りは持続します。ただし、React Nativeのメジャーアップデート時には再確認が必要です。

まとめ

ViewPropTypesの警告問題に対する最も堅牢な解決策は、方法1のモジュールリゾルバーを使用する方法です。これはReact Nativeのアップデートに強く、サードパーティライブラリが更新されるまでの間、安全に問題を回避できます。

根本的には、PropTypesに依存しているライブラリの更新や、TypeScriptへの移行を検討することが長期的な解決策となります。