diff --git a/Libraries/Utilities/warnOnce.js b/Libraries/Utilities/warnOnce.js new file mode 100644 index 00000000000000..8f7350444f15b4 --- /dev/null +++ b/Libraries/Utilities/warnOnce.js @@ -0,0 +1,34 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @format + * @flow + */ + +'use strict'; + +const warning = require('fbjs/lib/warning'); + +const warnedKeys: {[string]: boolean} = {}; + +/** + * A simple function that prints a warning message once per session. + * + * @param {string} key - The key used to ensure the message is printed once. + * This should be unique to the callsite. + * @param {string} message - The message to print + */ +function warnOnce(key: string, message: string) { + if (warnedKeys[key]) { + return; + } + + warning(false, message); + + warnedKeys[key] = true; +} + +module.exports = warnOnce; diff --git a/Libraries/react-native/react-native-implementation.js b/Libraries/react-native/react-native-implementation.js index e9b7e56aba1939..d14722973dd932 100644 --- a/Libraries/react-native/react-native-implementation.js +++ b/Libraries/react-native/react-native-implementation.js @@ -11,10 +11,7 @@ 'use strict'; const invariant = require('invariant'); - -let showedListViewDeprecation = false; -let showedSwipeableListViewDeprecation = false; -let showedWebWiewDeprecation = false; +const warnOnce = require('warnOnce'); // Export React, plus some native additions. module.exports = { @@ -62,14 +59,11 @@ module.exports = { return require('KeyboardAvoidingView'); }, get ListView() { - if (!showedListViewDeprecation) { - console.warn( - 'ListView is deprecated and will be removed in a future release. ' + - 'See https://fb.me/nolistview for more information', - ); - - showedListViewDeprecation = true; - } + warnOnce( + 'listview-deprecation', + 'ListView is deprecated and will be removed in a future release. ' + + 'See https://fb.me/nolistview for more information', + ); return require('ListView'); }, get MaskedViewIOS() { @@ -121,14 +115,11 @@ module.exports = { return require('SwipeableFlatList'); }, get SwipeableListView() { - if (!showedSwipeableListViewDeprecation) { - console.warn( - 'ListView and SwipeableListView are deprecated and will be removed in a future release. ' + - 'See https://fb.me/nolistview for more information', - ); - - showedSwipeableListViewDeprecation = true; - } + warnOnce( + 'swipablelistview-deprecation', + 'ListView and SwipeableListView are deprecated and will be removed in a future release. ' + + 'See https://fb.me/nolistview for more information', + ); return require('SwipeableListView'); }, get Text() { @@ -165,15 +156,12 @@ module.exports = { return require('VirtualizedList'); }, get WebView() { - if (!showedWebWiewDeprecation) { - console.warn( - 'WebView has been extracted from react-native core and will be removed in a future release. ' + - "It can now be installed and imported from 'react-native-webview' instead of 'react-native'. " + - 'See https://github.com/react-native-community/react-native-webview for more informations.', - ); - - showedWebWiewDeprecation = true; - } + warnOnce( + 'webview-moved', + 'WebView has been extracted from react-native core and will be removed in a future release. ' + + "It can now be installed and imported from 'react-native-webview' instead of 'react-native'. " + + 'See https://github.com/react-native-community/react-native-webview for more informations.', + ); return require('WebView'); },