Skip to main content

React Native 0.71: TypeScript by Default, Flexbox Gap, and more...

· 11 min read
Matt Carroll
Matt Carroll
Developer Advocate at Meta
Nick Gerleman
Nick Gerleman
Software Engineer at Meta
Nicola Corti
Nicola Corti
Software Engineer at Meta
Lorenzo Sciandra
Lorenzo Sciandra
Senior Software Engineer at Microsoft

Today we’re releasing React Native version 0.71! This is a feature-packed release including:

In this post we’ll cover some of the highlights of 0.71.

info

For a full list of changes, check out CHANGELOG.md.

TypeScript by default

In this release, we’re investing in the TypeScript experience of React Native.

Starting with 0.71, when you create a new React Native app via the React Native CLI you'll get a TypeScript app by default. The new project is already set up with a tsconfig.json so out of the box your IDE will help you write typed code right away.

We’re also offering built-in, more accurate TypeScript declarations directly from the react-native package. This means you won’t need @types/react-native any longer, and the types will be updated in lockstep with React Native releases.

Finally, our documentation has been updated to feature TypeScript for all examples.

note

After upgrading to React Native 0.71, we recommend removing @types/react-native from your package.json devDependencies.

For more details on this change, including migration steps and how this affects Flow users, check out our previous post First-class Support for TypeScript.

Simplifying layouts with Flexbox gap

With React Native you can flexibly layout components on different screen sizes using Flexbox. Browsers have supported the Flexbox properties gap, rowGap, and columnGap, which allow you to specify the amount of space between all items in a Flexbox.

These properties have been long requested in React Native, and 0.71 adds initial support for gaps defined using pixel values. In future versions, we will add support for more values, such as percentages.

To see why this is useful, imagine trying to build a responsive layout with variably sized cards, 10px apart from each other, hugging the edges of the parent container. Trying to accomplish this layout with child margins can be tricky.

The following shows a layout where we start by giving each child margin: 10 style:

Two diagrams. On the left it shows a skeleton of an app with three boxes that have margin around them cause the boxes to have margin around all sides. On the right, the same diagram is shown highlighted to demonstrate the margin on all sides.

Margins are applied uniformly to the edges of all children and don’t collapse under Flexbox, giving us spacing at the exterior of the cards, and double the space on the interior compared to what we wanted. We can get around this by applying non-uniform margins, using negative margins on the parent, halving our intended spacing, etc, but it can be made much easier.

With flex gap, this layout can be achieved by setting gap: 10 on the container for a 10 pixel gap between the interior of the cards:

Two diagrams. On the left it shows a skeleton of an app with three boxes that have margin only on the inner sides and not the outer sides of the boxes due to the Flexbox gap property. On the right, the same diagram is shown highlighted to demonstrate the margin only on the inner sides.

For more information on Flexbox gaps, see this blogpost from CSS Tricks.

Web-inspired props for accessibility, styles, and events

This release includes a number of new props inspired by web standards to align React Native’s APIs across many platforms. These new props are purely additive so there are no expected migrations or change of behavior for equivalent accessibility, behavior, or style props.

For any new prop alias introduced, if there is an existing prop with a different name and both are specified, the new alias prop value will take precedence. For example, this release adds a src prop alias for source on the Image component to align with the src prop on web. If both src and source are provided, the new src prop will be used.

note

For more background on aligning React Native to web standards, check out this proposal and related discussion.

Accessibility

We introduced ARIA props as alias to existing React Native accessibility props.

These props now exist on all core components of React Native:aria-label, aria-labelledby,aria-modal, id, aria-busy, aria-checked, aria-disabled, aria-expanded, aria-selected, aria-valuemax, aria-valuemin, aria-valuenow, and aria-valuetext.

We also introduced equivalent web behavior for: aria-hidden, aria-live, role, and tabIndex.

See this issue for more details.

Component-Specific Behavior

There were also props introduced to align prop names with equivalent DOM prop names for core components.

  • Image: alt, tintColor, crossOrigin, height, referrerPolicy, src, srcSet, and width.
  • TextInput: autoComplete, enterKeyHint, inputMode, readOnly, and rows.

See this issue for more details.

Styles

To align with certain CSS styles, there have been feature extensions for the following styles:

The following aliases have been added to shadow existing React Native styles:

See this issue for more details.

Events

Finally, we also added an opt-in implementation of PointerEvents

Once enabled, the following handlers on View will support hover:

  • onPointerOver, onPointerOut
  • onPointerEnter, onPointerLeave

These events are also implemented in Pressability for new opt-in support for hover.

To enable these features, set the following flags to true:

import ReactNativeFeatureFlags from 'react-native/Libraries/ReactNative/ReactNativeFeatureFlags';

// enable the JS-side of the w3c PointerEvent implementation
ReactNativeFeatureFlags.shouldEmitW3CPointerEvents = () => true;

// enable hover events in Pressibility to be backed by the PointerEvent implementation.
// shouldEmitW3CPointerEvents should also be true
ReactNativeFeatureFlags.shouldPressibilityUseW3CPointerEventsForHover =
() => true;
note

You’ll also need to enable React feature flags on your Android and iOS native setup.

Check out our dedicated PointerEvents post to learn more.

Restoring PropTypes

React Native’s prop types, such as ViewPropTypes and Text.propTypes, were deprecated in 0.66 and accessing them would output deprecation warnings. When they were removed in 0.68, many developers began experiencing errors when upgrading to the latest version of React Native.

After some investigation, we realized that a couple issues prevented the community from taking action on the deprecation warnings. First, the deprecation warning was not always actionable which caused people to ignore them (issue one, issue two). Second, the deprecation warnings were being incorrectly filtered by LogBox.ignoreLogs. Both of these have now been fixed, but we want to give people more time to upgrade the deprecated call sites.

So in this release we are adding back React Native’s propTypes so that it is easier for people to upgrade and migrate their code to avoid using them. The deprecated-react-native-prop-types package has also been updated for all of the props in 0.71. In the future, we plan to proceed with the deprecation and remove prop types once again. We expect that when we revisit the removal, the community will experience significantly fewer issues.

caution

As part of this change, we are also removing the console filtering from LogBox.ignoreLog. This means logs that you have previously filtered with Logbox.ignoreLog will start appearing again in the console when you upgrade.

This is expected, because it allows logs such as deprecation warnings to be found and fixed.

Developer Experience Improvements

React DevTools

In this release, we've brought two popular React DevTools features on web to React Native.

"Click to inspect" is the option in the top left corner of React Dev Tools that allows you to click on an item in the app to inspect it in Dev Tools, similar to the Chrome element inspector.

Component highlighting will highlight the element you select in DevTools in the app so you can see which React components line up with which on-screen elements.

Here are both features in action:

Video of the behavior described above in action. On the left is a React Native app running in an iPhone simulator. On the right is the React DevTools. In both workflows, clicking on an item in the DevTools highlights the corresponding components in the app.

Hermes

In React Native 0.70, we made Hermes the default engine for React Native.

In React Native 0.71, we’re upgrading Hermes with a few notable improvements:

  • Improve source maps: By loading source maps over the network with Metro we’ve restored the ability to use source maps in recent versions of Chrome Dev Tools outside of Flipper.
  • Improve JSON.parse performance: This version includes a performance optimization that improves the performance of JSON.parse up to 30%.
  • Add support for .at(): Hermes now supports.at() for String, TypedArray, and Array.

For a full list of changes see the Road to 71 issue.

New Architecture

This release brings many improvements to the experimental New Architecture experience based on user feedback and reports we collected so far.

  • Reduced build times: The new distribution model uses Maven Central, which allows us to greatly reduce the build time on Android, resolves many build problems on Windows, and provides a more seamless experience with the New Architecture. Read more here.
  • Write less C++ code: You can now enable the New Architecture without having to add any C++ code in your app and the CLI app template has been cleaned of all the C++ code and the CMake files. Read more here.
  • Better encapsulation of iOS app setup: On iOS, we followed a similar approach to Android and encapsulated most of the logic to set up the New Architecture in the RCTAppDelegate class, which will simplify upgrades in the future with fewer manual breaking changes.
  • Better dependency management on iOS: For library maintainers, we've added a new install_module_dependencies function to call inside your package podspec which will install all the required dependencies for the New Architecture.
  • Bug fixes and better IDE support: we fixed several bugs and issues (like better IDE support for Android) that were reported by our users in the New Architecture Working Group.

As a reminder, the New Architecture is still an experimental API experience as we iterate on changes to make adoption easier. Please try out the new simplified steps in the New Architecture documentation and post any feedback you have to the New Architecture Working Group.

Other Notable Fixes

  • Better stack frame collapsing: We've updated the list of internal frames for React Native so LogBox will show your code more often rather than internal React Native frames, helping you to debug issues faster.
  • Build time improvements: We migrated assets to Maven Central for prefabs to improve build times (both iOS and Android) for Hermes in both the current and new architectures.
  • Android template improvements: The Android template was heavily cleaned and now fully relies on the React Native Gradle Plugin. You can find the configuration instructions directly inside the template or in the new dedicated page on the website.

Breaking changes

  • Changes to Console Logging: LogBox.ignoreLog no longer filters console logs. This means you will start seeing logs in the console that you have silenced in LogBox. See this comment for more details.
  • Removed AsyncStorage and MaskedViewIOS: These components have been deprecated since version 0.59, so it’s time we remove them entirely. For alternatives, please check React Native Directory for community packages that cover those use cases.
  • JSCRuntime moved to react-jsc: react-jsi is now split into react-jsc and react-jsi. If you use JSCRuntime, you will need to add react-jsc as a dependency (facebook/react-native@6b129d8).

Acknowledgements

This release is possible thanks to the work of 70+ contributors adding over 1000 commits.

We especially want to thank those who contributed to these major React Native projects:

Finally, thanks to @cortinico, @kelset, @dmytrorykun, @cipolleschi, and @titozzz for cutting this release!

Try out 0.71.0 now!

For React Native CLI users, see the upgrade documentation for how to update your existing project, or create a new project with npx react-native init MyProject.

React Native version 0.71 will be supported in Expo SDK version 48.

info

0.71 is now the latest stable version of React Native and 0.68.x versions are now unsupported. For more information see React Native’s support policy.