React Native

https://reactnative.dev/docs/components-and-apis

CLI

  • Run specific simulator: npm run ios -- --simulator="iPhone SE (1st generation)"
  • Reset cache: yarn start --reset-cache
  • Full clean (add extra steps as you find necessary):
rm -fr ios/build ios/Pods node_modules && yarn install && (cd ios; pod install) && yarn start --reset-cache

Components

<FlatList
  data={array}
  keyExtractor={item => item.id}
  renderItem={({ item }) => ...}
/>

Testing

transformIgnorePatterns is actually specifying which NPM packages you should transform, since their sources aren’t transpiled:

https://jestjs.io/docs/tutorial-react-native#transformignorepatterns-customization

Detecting Rerenders

This does not work for me in Flipper or React Native Debugger; they give an error about an incorrect react-devtools version.

Fix is to install and run react-devtools instead of Flipper or React Native Debugger, using the version they specify:

$ npm i -g react-devtools@"<4.11.0"
$ react-devtools

(notice the quotes; Flipper says the wrong thing)

  • Go to Components tab
  • Click Gear then check Profiler > Record why each component rendered while profiling
  • Click Profiler, then blue button to record
  • Do action that causes rerender
  • Click red button to stop recording
  • Click through steps at top, and find component at bottom. It will say “Why did this render?” and probably just “Hooks changed”, which is not that useful

SVG

https://github.com/software-mansion/react-native-svg#installation https://github.com/kristerkari/react-native-svg-transformer#installation-and-configuration

// package.json
{
  //...
  "jest": {
    //...
    "moduleNameMapper": {
      "\\.svg": "<rootDir>/__mocks__/svgMock.js"
    }
  }
}
// __mocks__/svgMock.js
module.exports = 'SvgMock';
module.exports.ReactComponent = 'SvgMock';

CLI

$ yarn add react-native-svg
$ npx pod-install
$ yarn add --dev react-native-svg-transformer
// metro.config.js
const { getDefaultConfig } = require("metro-config");

module.exports = (async () => {
  const {
    resolver: { sourceExts, assetExts }
  } = await getDefaultConfig();
  return {
    transformer: {
      babelTransformerPath: require.resolve("react-native-svg-transformer")
    },
    resolver: {
      assetExts: assetExts.filter(ext => ext !== "svg"),
      sourceExts: [...sourceExts, "svg"]
    }
  };
})();

Expo

$ expo install react-native-svg
$ yarn add --dev react-native-svg-transformer
// metro.config.js
const { getDefaultConfig } = require("expo/metro-config");

module.exports = (() => {
  const config = getDefaultConfig(__dirname);

  const { transformer, resolver } = config;

  config.transformer = {
    ...transformer,
    babelTransformerPath: require.resolve("react-native-svg-transformer"),
  };
  config.resolver = {
    ...resolver,
    assetExts: resolver.assetExts.filter((ext) => ext !== "svg"),
    sourceExts: [...resolver.sourceExts, "svg"],
  };

  return config;
})();