Releases: facebook/react-native
v0.8.0
0.8.0 has been published to npm and CocoaPods. The major features of this release are the Animated library and the move from Node to io.js.
0.9.0-rc is scheduled for next Friday once some small breaking changes to the Touchable components are all merged.
The changes for this release are covered in the 0.8.0-rc and 0.8.0-rc.2 release notes (0.8.0 is the same as 0.8.0-rc.2).
v0.8.0-rc.2
v.0.8.0-rc.2 includes a few commits to improve the stability of the next release.
- Reverted removal of layout-only UIViews and a related fix for sticky headers in scroll views
- Fixed TextInput so it no longer mutates props; it no longer warns in development
- Fixed ListView crash related to getting its scroll responder
v0.8.0-rc
0.8.0-rc and 0.7.1 proper have been published to npm and CocoaPods! This round of updates includes some very exciting enhancements from both Facebook and the React Native community. Thank you to all the contributors who submitted PRs, reviewed code, and investigated issues!
Animated
The newest animation API is called Animated
, you can import it with var { Animated, } = require('react-native')
, as you would other React Native components. @brentvatne speaking here in saying that I'm incredibly excited about this - @vjeux and @sahrens deserve a round of 👏 for their hard work over the last few months. What we see in this API is a coalescing of great ideas from the best-in-class animation libraries, such as POP and the D3 transition API, with a declarative React flavor.
- Declarative animations: not only does this make our code easier to read and write, it allows for future optimizations such as pre-calculating keyframes in JavaScript and sending them over to be run on the main thread.
- Performant rendering is accomplished by calling setNativeProps rather than
setState
to avoid re-rendering your entire component on each animation frame, and by leveraging the InteractionManager to defer expensive operations while an animation is running. - Interpolators take care of converting values between different units. For example, often with animations you are dealing with gestures and you will want to convert the x or y position of that gesture to some other value, such as opacity. Interpolators allow you to declaratively specify how those values map to each other. See the Interpolation section of the docs for more information.
- Most animations that we see today can be expressed with springs (think of pulling a tree branch down and watching it bounce back to its resting state, oscillating around it before settling), decay (think of rolling a ball on grass, it starts at a high initial velocity and decelerates overtime), and timed easings (see easings.net). These are built in to
Animated
.
Going forward, it is recommend that you write your animations using Animated
or LayoutAnimation.
Check out the Animated docs, the UIExplorer Animation Example, and this other example to learn more.
We strongly encourage you all to implement the most difficult animations that you can imagine, share the results and create any issues if you have suggestions for how to improve the API. Enjoy!
Moving to io.js
Earlier this year, a fork of Node.js called io.js made its debut and most of the development effort on Node shifted to io.js. For most intents and purposes, io.js is the modern version of Node and the two projects are planning to reconcile by using the io.js codebase and the Node.js name; when they converge, Node.js will be based on io.js's code under the hood.
And now, some projects like jsdom support only io.js, which affects their dependents like jest. So because React Native has dependencies that require io.js and to generally stay up-to-date and benefit from performance and security improvements in its V8 JavaScript engine, React Native will target io.js.
Installing/upgrading to io.js
There are several ways to upgrade to io.js:
Homebrew: brew is a great package manager for OS X. After installing brew, run:
brew unlink node # Removes "node" from your path
brew install iojs # Downloads the latest version of io.js
brew link iojs --force # Tell brew that you want to run io.js when you run "node"
To stay up-to-date, run brew update && brew upgrade iojs
.
nvm: nvm is an awesome tool for downloading and switching between different versions of Node and io.js. After installing nvm, run:
nvm install iojs-v2 # Downloads the latest version of io.js 2.x
nvm alias default iojs-v2 # Tells nvm to use iojs-v2 when you open a terminal
To stay up-to-date, run nvm install iojs-v2
. You may want to copy over your globally installed npm packages with nvm reinstall-packages iojs-v2.x.y
, where 2.x.y
is the specific version of io.js you were previously using.
OS X Installer: There is an installer for OS X at https://iojs.org/en/index.html. To keep up-to-date, re-download the installer each time the io.js community publishes a new one.
Breaking Changes
- Contributors to React Native should upgrade to io.js. React Native is now using jest 0.5.x, which runs only on io.js, so you will need to upgrade in order to run the JS tests.
- Upgrade Flow to 0.13.1 if you are using static type checking
Known Issues
- NavigatorIOS transitions from JS occasionally do not work #1933
Deprecations
No APIs were deprecated.
New Features
JavaScript
- Animation API: As mentioned above, there is a new API for animating components. See the animation documentation to learn more.
- Text decoration: The Text component supports various CSS-like decoration props:
textDecorationColor
,textDecorationLine
, andtextDecorationStyle
. See UIExplorer and the documentation for the supported values. - Opaque nav bar:
NavigatorIOS
has a new prop calledtranslucent
. Set it tofalse
to turn the nav bar opaque. - Scroll view composition:
ListView
has a new prop calledrenderScrollComponent
. Set it to a function that takesprops
and returns a scroll view element. This allows you to return custom scroll views. - Image load events: The Image component supports three new events for downloaded images:
onLoadStart
,onLoadProgress
, andonLoadError
- System font: There is a special font family called "System" that tells Text components to use the system font. Apps on iOS 9 will use San Francisco instead of Helvetica Neue. In addition, the system font on iOS is configured with several typographical options like the widths of digits and vertical positioning of colons that the Apple font team has chosen.
iOS
- Fewer UIViews: Improved rendering performance by eliding UIViews for shadow views that solely affect layout. 02db374
- RCTResponseErrorBlock: Authors of native modules now can use
RCTResponseErrorBlock(NSError *)
instead ofRCTResponseSenderBlock(id)
to pass errors back to JavaScript. - NSSet coercion: Native module methods now can have parameter of type
NSSet
.RCTConvert
will automatically convert JavaScript arrays toNSSet
objects.
Packager
- Custom transformers: You can pass
--transform /a/path/to/a/transformer.js
to the packager to customize how it transforms your app's JavaScript source code. - Faster Babel: The packager uses a faster version of babel-core for a 40% improvement in transformation 7d184ad
- io.js and V8: io.js includes a modern version of V8, which improves the packager's performance by around 5-10%
Bug Fixes
- Improved scene and focus management in Navigator 7963add e3e6098
- Windows support for the packager. #893
- Fix crash when running with Address Sanitizer with Xcode 7 #1712
- A method previously named
tick
has been renamed to pass iTunes Connect validation #1722 - InteractionManager no longer warns if the user performs a gesture for longer than two seconds 776dc97
- Data from older scroll events is no longer dropped coalescing them #1782
- Native ListView child frames are kept in sync with the JavaScript component 66d3f3c
- The XHR polyfill properly lowercases response headers internally #1876
- Fix crash when getting current thread name and include in prod traces #1833 #1868
v0.7.0-rc
After a few days of unavoidable delays, 0.7.0-rc and 0.6.0 proper have been shipped to npm! 0.6.0 proper is up on Cocoapods as well, and the 0.7 stable release will be pushed to it next week.
I want to send out a big thanks to everyone who submitted issues and pull requests this time around! Your efforts are much appreciated.
Improved Profiler
We mentioned in the v0.6.0-rc release notes that @tadeuzagallo had been working on improving the performance tooling, and now with v0.7.0-rc it's available for you to use!
The profiler integrates with Chrome Trace Viewer to give you fine-grained insight into both the JavaScript and Objective-C stacks in one place. You can also visualize VSync/frame deadlines (iOS is VSynced at 60fps) and enable "Flow events", which draws arrows to indicate function calls flowing into one another.
Install Google Trace Viewer
You will need to have trace2html
in your PATH
in order to use the profiler.
brew update && brew install trace2html
Using the Profiler
Command+D > Start Profiler
, perform whatever actions that you would like to profile in your app, then Command+D > Stop Profiler
.
After a short delay the results will be opened up automatically in Chrome. Let's look at the results from the profile we recorded above.
Not very useful at this high level, but we can tell that there are a couple places where we clearly exceeded the frame deadline of 16.67ms (60fps). You probably noticed this in the gif above - clicking the button did not immediately change the background color. In this case, it was because I inserted for (var i = 0; i <= 100000000; i++) { i * i }
into the onPress
handler to slow it down; in practice, this could be due to an actual performance issue in your app.
Clicking on DispatchFrameUpdate reveals that it took over 500ms to calculate the frame - more than 30x what it should take. But the time spent on DispatchFrameUpdate itself (the "self time") is insignificant, so we dig deeper.
Everything looks good except for the function call at the very bottom - there we find that the code for responding to the touch event is responsible for egregiously missing the frame deadline. If we were to move the slow code down into the render function, we would see this instead:
We can also select "Highlight VSync" to see where VSync is occurring:
And if we select "Flow Events" we can see how functions flow into one another.
Note: the simulator is unreliable for this kind of profile because the timing is not the same as on the device; you might notice the VSync values on the UI thread and JS threads are completely different in simulator profiles.
Breaking Changes
- Removed contextual navigation from
Navigator
(4690983). If you use nestedNavigator
components, you must explicitly call navigation methods likepush
,pop
, andreplace
on the parentNavigator
instead of relying on the child to automatically delegate the call to its parent. - XHR requests will throw an error if the response is anything other than text (see #1870)
- The packager follows Node's
require
resolution algorithm much more closely. When in doubt, specify the path to modules the same way you would with Node. - The Facebook-proprietary
@providesModule
directive is now scoped to each npm package instead of your entire app. This means that if you were requiring modules from another package using its@providesModule
name, this will no longer work. Instead, require the modules using the package's name like you would with Node. - All
require
statements for React Native modules should go through the public interface:
// This may pull in an unexpected version of `RCTDeviceEventEmitter` and `NativeModules`
var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');
var RNKeyboardEventsManager = require('NativeModules').RNKeyboardEventsManager
becomes
// This will ensure that you require the correct modules, via the react-native package
var {
DeviceEventEmitter,
NativeModules: {
RNKeyboardEventsManager,
},
} = require('react-native');
Deprecations
onWillFocus
andonDidFocus
have been deprecated in favor of adding event listeners to the navigator:this.props.navigator.addListener('willfocus', this._onWillFocus);
andthis.props.navigator.addListener('didfocus', this._onDidFocus);
New Features
- Add
assetRoots
andprojectRoots
flags to thebundle
CLI command to conform with packager - Add support for incremental updates to XMLHttpRequest (e00b9ac and UIExplorer for more details)
- Add map type property (standard, satellite, hybrid) to MapView
- Add
getScrollResponder
toScrollView
-based components, such asListView
, to allow for better composability - File upload via XHR FormData
- Support
textAlign: 'justify'
on iOS - Add support for JavaScript async functions to
RCT_EXPORT_METHOD
(90439ce - also see @ide's blog post) - Documentation added for Animations, Direct Manipulation (setNativeProps), Navigator vs NavigatorIOS comparison, ActionSheetIOS, Accessibility and various other improvements.
- Add scale support for base-64 encoded images
- Automatically dismiss red box error screen on live reload for a better development experience
- Packager has a new module resolution algorithm that more closely matches Node's for
node_modules
- Improved packager performance by lazily building the dependency graph asynchronously
Bug Fixes
- Allow external libraries to define React Native modules instead of previously requiring everything to be compiled together as one library (e9095b2)
- Text layout bug on screen rotation
- Update curRenderedRowsCount when data source changes - fixes need to sometimes force a re-render of
ListView
- Fix
AnimationExperimental
for 32bit devices whenfromValue
is double - Enable
textAlign
forTextInput
v0.6.0-rc
168 commits, 48 contributors.
We just shipped 0.6.0-rc and 0.5.0 proper to npm.
Last Friday, @brentvatne, @ide, @jsierles, @christopherdro, @dsibiski and @ccheever organized a big issue triage. They closed more than 200 issues, and properly tagged and found call to actions on the 200 remaining. In addition, they came up with a very useful document which lists the top 10 problems that are affecting the community. This is going to be very useful to prioritize our work.
Inspect Element
When you are working on a large codebase, one developer cannot fit all the code in his or her head. So, when you want to work on something, the first thing that you need to figure out is where is the code that rendered this piece of UI. @jaredly and @frantic made this super easy by implementing Inspect Element.
In order to use it, press Command+D > Inspect Element > Tap anywhere on the screen.
It is loaded with features such as showing you all the styles applied to the element, the dimensions/padding/margin and ability to go up the hierarchy. This has the potential of greatly increasing your productivity! Let us know if you have more ideas on how to make it even more useful.
Switch to Babel
Facebook has been one of the first big adopters of ES6 and we have several people participating in the TC39 committee that designs the spec. Since the JavaScript transform landscape was almost inexistent several years ago, we implemented and used our own transpiler called jstransform.
Unfortunately, jstransform has a big architectural issue: it takes an AST as an input and plain text as an output. The consequence is that you cannot compose transforms easily, which is very problematic when you want to try out new language features. We started working on a new version that solves this problem with a project called Recast, which is doing AST -> AST transforms.
Recast is the framework powering esnext and regenerator. While those projects were moving along, a new player entered called Babel (previously 6to5) and all the people working on esnext and regenerator joined forces with Babel.
At this point, Babel supports more features than jstransform, has a better architecture and a super active community. We already switched to Babel for React and we followed suite on React Native thanks to @amasad, @DmitrySoshnikov and @jaredly.
Another advantage is that we can now run the awesome ESLint on the raw source instead of the transformed source which is going to make it much more useful.
It shouldn't impact you right now as we did not enable any new transforms, but we're looking into letting you configure which transforms you want to use.
Background Color Propagation
In all the popular UI frameworks such as web, iOS, Android, the default background color for elements is transparent. This is usually what the developer expects but it makes it a hard problem for the compositing engine: every element that needs to be displayed on screen can potentially be blended with the elements that are underneath. This means that you have to do multiple passes and lose some of the parallelism of the GPU.
What we found is that the vast majority of the time, what the developer wants is not to have a transparent background color but to inherit the background color of its parent. When doing that, the job of the compositing engine is much simpler: since the background has a solid color, it will not need to compute what's underneath to get that pixel color.
There are some rare but legitimate use cases when this propagation is not correct, for example if you want to overlay transparent images on-top of each others. In this case, you can write ``style={{backgroundColor: 'transparent'}}` to lose this optimization and go back to the platform default.
In order to figure out how much blending is happening, you can turn on the setting in your simulator:
This background color propagation mechanism existed since we open sourced. However, there were many cases where it didn't remove blending as expected. For example, it turned out that giving a solid background color to images did not help the compositing engine the way it was implemented. @nicklockwood fixed this particular case (and many more) and you can see that images are now green :)
As you can see, there's still some red in React Native part and some red in default iOS components. There's still work to do to improve blending, but the new defaults are much better :)
Performance Tooling
The best way to improve performance is to be able to measure and visualize what is happening. This is something that is challenging with React Native since we have to profile two completely different stacks: obj-c and js. @tadeuzagallo figured out that he could add profiling markers in the code and export it in a format that's compatible with Chrome Trace Viewer to be able to visualize it.
Having this new tool, it helped us find out inefficiencies in the code. For example, on every JavaScript round-trip, we found out that we traversed the entire view hierarchy on the main thread! The reason for that particular case is that we have a method called reactBridgeDidFinishTransaction that was used to do some cleanup for 3 components: ScrollView, TabBarIOS and NavigatorIOS. It was implemented in a naive way where we would traverse all the views and for each one check if it implements that method and if yes, call it. It took 10ms on an iphone 6 to traverse a view hierarchy of 5k elements!
Once we discovered that, we changed it to register those components so that we only traverse a list of a few elements and we fixed this big inefficiency as you can see in the screenshot below:
The process to get this trace is currently very manual but I wanted to let you know that we're working on it and that it is likely going to help us diagnose more performance issues in the future!
Breaking Changes
- The enum values
StatusBarIOS.Style.default
andStatusBarIOS.Style.lightContent
were removed in favor of the strings"default"
and"light-content"
, respectively
Please let me (@vjeux) know if you run into any trouble upgrading.
New Features
- Implement merge functionality on AsyncStorage
- Add custom delay props to
<Touchable*>
<ListView>
now supports a renderSeparator prop- Support fetching videos from Camera Roll
Bug Fixes
- Use a faster implementation of crc32
- Warn when trying to require a native component that doesn't exist
- Fix XHR.status which is a number and not a string
- Use JSC C API for a 10-15% perf improvement in this particular bridge function
- Add better error messages when using react-native-cli incorrectly
- Geolocation now invalidates timer after success or error callback
- Upgrade Travis to the latest version of Xcode
- Remove useless setInterval on ListView
- Many Navigator small fixes
- Fix accessibility issue with ScrollView
- Fix itemList updates on PickerIOS
- Better resolution rules for node_modules in packager and support packages with . in the name
v0.5.0-rc
45 commits and 21 contributors.
New Features
FPS Monitor
One of the reason you may want to use React Native is because you can build applications that perform well with it. As React Native matures in term of features, we are starting to invest a lot more into performance. If you open the developer panel via Cmd+Ctrl+Z, you will see a new option called "Show FPS Monitor".
When activated, you will see two FPS counters, one for the UI thread and one for the JS thread. The best way to make an application fast is to fix the slow parts. This is where performance investigation tooling is required. This one lets you do a first triage between issues from the UI thread and the JS thread. This is the first of a series of performance tooling we're working on.
Please, do not ever profile on simulator as it doesn't reflect at all what on device performance is going to be. Also, make sure that you dev mode is turned off as it introduces non trivial overhead to provide great developer warnings.
Accessibility
Facebook is being used by 1.4 billion people around the world and we want every single one of them to have the best experience possible. Accessibility features are an important tool and one that has traditionally been very developer unfriendly.
Our goal with React Native is that if you write your app without thinking about accessibility: it will be 80% there. We want you to fall into the pit of success.
In order to make an app accessible via Voice Over, you need to identify all the interactive elements and mark them as accessible with a label. It turns out that if you follow React Native best practices, most of your interactive elements are going to be implemented via <TouchableHighlight>
, <TouchableOpacity>
or <TouchableWithoutFeedback>
. We made sure to mark those as accessible. In order to compute the label, we traverse the hierarchy and concatenate all the text nodes. Most of the time it gives a good result. The place where it breaks down most often is when the button is an icon. In those cases, you need to specify the label yourself via the accessibilityLabel
prop.
To check if your app is accessible, you can enable the Accessibility Inspector by doing: Hardware > Home > Settings > General > Accessibility > Accessibility Inspector. And go back to your app via Hardware > Home > Your app.
All the text outside of touchable elements is also marked as accessible by default as the user is likely going to want to know about it. Since React Native uses native components such as UIScrollView and UIButton, you also get their great accessibility features.
As you can imagine, those heuristics do not work all the time. You can polish the accessibility via the following props: accessible
, accessibilityLabel
, onAcccessibilityTap
, onMagicTap
, accessibilityTraits
.
This is an area that's often overlooked and where we hope React Native can shine. If you are interested in helping out with this effort, please let us know.
Breaking Changes
AdSupport
is no longer linked by default. The mere existence of code that uses the advertising id in your app triggers an additional verification step during the App Store review process :( If you are using it, you'll need to manually link it to continue using it.
Bug Fixes
- Add
RCTNativeAppEventEmitter
as mentioned in the documentation - Add a warning when trying to
react-native init
in an already initialized folder onLayout
is now available on<ActivityIndicatorIOS>
and<TextInput>
- Update Jest to 0.4.5
- Fix RCTBatchedBridge main thread invalidation
- Fix exception when creating a native component with no propTypes
- Fix edge cases in
<Navigator>
- Red box if JSC throws a syntax error not previously caught by the packager
v0.4.4
v0.4.3
91 commits, 23 contributors, 9 days
New Features
Websocket
polyfillAlertIOS.prompt()
letterSpacing
style property for<Text>
borderTopLeftRadius
,borderTopRightRadius
... style property on<View>
Breaking Changes
ref.getNativeHandle()
andref.getNodeHandle()
no longer exist. The replacement isReact.findNodeHandle(ref)
- If you were using the undocumented
createReactIOSNativeComponentClass
orReactIOSViewAttributes
to create iOS wrappers, now you should userequireNativeComponent
Updates
- Update flow to 0.11
- Update jest to 0.4.2
Bug Fixes
- Fix packager with folders that have space inside
- Fix thread safety for RCTImageLoader
- Properly support overflow: 'visible' on
<ScrollView>
- measure callback can no longer be invoked if the component has unmounted
- No longer require
ruby
dependency - UIExplorer icon shows up on the home screen
- Changing left icon now works on
<NavigatorIOS>
- Fix edge cases in
<Navigator>