Summary:
Fixes https://github.com/facebook/react-native/issues/34034.
The FlatList doesn't call renderItem on nullish values when numColumns > 1, but it does when numColumns is not set (or equals 1).
I think the behavior should be consistent, so I updated the code so renderItems is called for every items.
I believe the condition `item != null` was here to make sure renderItem isn't called for index outside of data range, so I replaced it with `itemIndex < data.length`.
## Changelog
<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
https://github.com/facebook/react-native/wiki/Changelog
-->
[General] [Fixed] - Fix FlatList not calling render items for nullish values when numColumns > 1
Pull Request resolved: https://github.com/facebook/react-native/pull/34205
Test Plan:
- I added a failing test corresponding to the issue, and the test now succeeds.
- I used the same code as in the test on a newly initialized app on RN 0.69 and made sure renderItem was called for every items as expected.
Reviewed By: NickGerleman
Differential Revision: D38185103
Pulled By: lunaleaps
fbshipit-source-id: 4baa55caef9574c91c43c047f9e419016ceb39db
Summary:
This diff is part of an overall stack, meant to fix incorrect usage of `setState()` in `VirtualizedList`, which triggers new invariant checks added in `VirtualizedList_EXPERIMENTAL`. See the stack summary below for more information on the broader change.
## Diff Summary
`_createViewToken()` is called during state changes. Use explicit props passed in.
## Stack Summary
`VirtualizedList`'s component state is a set of cells to render. This state is set via the `setState()` class component API. The main "tick" function `VirtualizedList._updateCellsToRender()` calculates this new state using a combination of the current component state, and instance-local state like maps, measurement caches, etc.
From: https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous
---
> React may batch multiple setState() calls into a single update for performance. Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state. For example, this code may fail to update the counter:
```
// Wrong
this.setState({
counter: this.state.counter + this.props.increment,
});
```
> To fix it, use a second form of setState() that accepts a function rather than an object. That function will receive the previous state as the first argument, and the props at the time the update is applied as the second argument:
```
// Correct
this.setState((state, props) => ({
counter: state.counter + props.increment
}));
```
---
`_updateCellsToRender()` transitively calls many functions which will read directly from `this.props` or `this.state` instead of the value passed by the state updater. This intermittently fires invariant violations, when there is a mismatch.
This diff migrates all usages of `props` and `state` during state update to the values provied in `setState()`. To prevent future mismatch, and to provide better clarity on when it is safe to use `this.props`, `this.state`, I overrode `setState` to fire an invariant violation if it is accessed when it is unsafe to:
{F756963772}
Changelog:
[Internal][Fixed] - Thread props to _createViewToken()
Reviewed By: genkikondo
Differential Revision: D38294339
fbshipit-source-id: dc215e267f126a3789742c14c35479f509822710
Summary:
This diff is part of an overall stack, meant to fix incorrect usage of `setState()` in `VirtualizedList`, which triggers new invariant checks added in `VirtualizedList_EXPERIMENTAL`. See the stack summary below for more information on the broader change.
## Diff Summary
`_onCellFocusCapture()` derives state from existing state, so it should be wrapped in a state updater to compare against the latest value in the batch.
## Stack Summary
`VirtualizedList`'s component state is a set of cells to render. This state is set via the `setState()` class component API. The main "tick" function `VirtualizedList._updateCellsToRender()` calculates this new state using a combination of the current component state, and instance-local state like maps, measurement caches, etc.
From: https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous
---
> React may batch multiple setState() calls into a single update for performance. Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state. For example, this code may fail to update the counter:
```
// Wrong
this.setState({
counter: this.state.counter + this.props.increment,
});
```
> To fix it, use a second form of setState() that accepts a function rather than an object. That function will receive the previous state as the first argument, and the props at the time the update is applied as the second argument:
```
// Correct
this.setState((state, props) => ({
counter: state.counter + props.increment
}));
```
---
`_updateCellsToRender()` transitively calls many functions which will read directly from `this.props` or `this.state` instead of the value passed by the state updater. This intermittently fires invariant violations, when there is a mismatch.
This diff migrates all usages of `props` and `state` during state update to the values provied in `setState()`. To prevent future mismatch, and to provide better clarity on when it is safe to use `this.props`, `this.state`, I overrode `setState` to fire an invariant violation if it is accessed when it is unsafe to:
{F756963772}
Changelog:
[Internal][Fixed] - Use correct form of setState() in _onCellFocusCapture()
Reviewed By: genkikondo
Differential Revision: D38293583
fbshipit-source-id: 1d0e5152e6c1757408e39dff225e07accc5ee49f
Summary:
This diff is part of an overall stack, meant to fix incorrect usage of `setState()` in `VirtualizedList`, which triggers new invariant checks added in `VirtualizedList_EXPERIMENTAL`. See the stack summary below for more information on the broader change.
## Diff Summary
Use supplied props in `_keyExtractor()`, which is used to map between frame index and identity.
## Stack Summary
`VirtualizedList`'s component state is a set of cells to render. This state is set via the `setState()` class component API. The main "tick" function `VirtualizedList._updateCellsToRender()` calculates this new state using a combination of the current component state, and instance-local state like maps, measurement caches, etc.
From: https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous
---
> React may batch multiple setState() calls into a single update for performance. Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state. For example, this code may fail to update the counter:
```
// Wrong
this.setState({
counter: this.state.counter + this.props.increment,
});
```
> To fix it, use a second form of setState() that accepts a function rather than an object. That function will receive the previous state as the first argument, and the props at the time the update is applied as the second argument:
```
// Correct
this.setState((state, props) => ({
counter: state.counter + props.increment
}));
```
---
`_updateCellsToRender()` transitively calls many functions which will read directly from `this.props` or `this.state` instead of the value passed by the state updater. This intermittently fires invariant violations, when there is a mismatch.
This diff migrates all usages of `props` and `state` during state update to the values provied in `setState()`. To prevent future mismatch, and to provide better clarity on when it is safe to use `this.props`, `this.state`, I overrode `setState` to fire an invariant violation if it is accessed when it is unsafe to:
{F756963772}
Changelog:
[Internal][Fixed] - Thread props to _keyExtractor()
Reviewed By: genkikondo
Differential Revision: D38293586
fbshipit-source-id: e50823bacdf45adad3b8b655d66d305a1762e9b8
Summary:
This diff is part of an overall stack, meant to fix incorrect usage of `setState()` in `VirtualizedList`, which triggers new invariant checks added in `VirtualizedList_EXPERIMENTAL`. See the stack summary below for more information on the broader change.
## Diff Summary
This forwards props to `__getFrameMetricsApprox()` and `_getFrameMetrics()` . This is called in a variery of places, so we need to pass `FrameMetricProps` through more places, and update public/test usage.
## Stack Summary
`VirtualizedList`'s component state is a set of cells to render. This state is set via the `setState()` class component API. The main "tick" function `VirtualizedList._updateCellsToRender()` calculates this new state using a combination of the current component state, and instance-local state like maps, measurement caches, etc.
From: https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous
---
> React may batch multiple setState() calls into a single update for performance. Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state. For example, this code may fail to update the counter:
```
// Wrong
this.setState({
counter: this.state.counter + this.props.increment,
});
```
> To fix it, use a second form of setState() that accepts a function rather than an object. That function will receive the previous state as the first argument, and the props at the time the update is applied as the second argument:
```
// Correct
this.setState((state, props) => ({
counter: state.counter + props.increment
}));
```
---
`_updateCellsToRender()` transitively calls many functions which will read directly from `this.props` or `this.state` instead of the value passed by the state updater. This intermittently fires invariant violations, when there is a mismatch.
This diff migrates all usages of `props` and `state` during state update to the values provied in `setState()`. To prevent future mismatch, and to provide better clarity on when it is safe to use `this.props`, `this.state`, I overrode `setState` to fire an invariant violation if it is accessed when it is unsafe to:
{F756963772}
Changelog:
[Internal][Fixed] - Thread props to __getFrameMetrics()
Reviewed By: genkikondo
Differential Revision: D38293591
fbshipit-source-id: c1499d722b69eb4b5953124ee8b8c3d15e912d93
Summary:
This diff is part of an overall stack, meant to fix incorrect usage of `setState()` in `VirtualizedList`, which triggers new invariant checks added in `VirtualizedList_EXPERIMENTAL`. See the stack summary below for more information on the broader change.
## Diff Summary
Use passed props in `computeWindowedRenderLimits()`, which is called during a state update.
## Stack Summary
`VirtualizedList`'s component state is a set of cells to render. This state is set via the `setState()` class component API. The main "tick" function `VirtualizedList._updateCellsToRender()` calculates this new state using a combination of the current component state, and instance-local state like maps, measurement caches, etc.
From: https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous
---
> React may batch multiple setState() calls into a single update for performance. Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state. For example, this code may fail to update the counter:
```
// Wrong
this.setState({
counter: this.state.counter + this.props.increment,
});
```
> To fix it, use a second form of setState() that accepts a function rather than an object. That function will receive the previous state as the first argument, and the props at the time the update is applied as the second argument:
```
// Correct
this.setState((state, props) => ({
counter: state.counter + props.increment
}));
```
---
`_updateCellsToRender()` transitively calls many functions which will read directly from `this.props` or `this.state` instead of the value passed by the state updater. This intermittently fires invariant violations, when there is a mismatch.
This diff migrates all usages of `props` and `state` during state update to the values provied in `setState()`. To prevent future mismatch, and to provide better clarity on when it is safe to use `this.props`, `this.state`, I overrode `setState` to fire an invariant violation if it is accessed when it is unsafe to:
{F756963772}
Changelog:
[Internal][Fixed] - Thread props to computeWindowedRenderLimits()
Reviewed By: genkikondo
Differential Revision: D38293588
fbshipit-source-id: 1330a003c1354bbd63c0b7b33a013e85e96fdc64
Summary:
This diff is part of an overall stack, meant to fix incorrect usage of `setState()` in `VirtualizedList`, which triggers new invariant checks added in `VirtualizedList_EXPERIMENTAL`. See the stack summary below for more information on the broader change.
## Diff Summary
Change `_updateViewableItems()` to accept an explicit set of props, and a CellRenderMask, instead of using `this.props` and `this.state`. The eventual sink are the `_getFrameMetric*` functions, so a minimal projection of props is added that we can pass through to it.
## Stack Summary
`VirtualizedList`'s component state is a set of cells to render. This state is set via the `setState()` class component API. The main "tick" function `VirtualizedList._updateCellsToRender()` calculates this new state using a combination of the current component state, and instance-local state like maps, measurement caches, etc.
From: https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous
---
> React may batch multiple setState() calls into a single update for performance. Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state. For example, this code may fail to update the counter:
```
// Wrong
this.setState({
counter: this.state.counter + this.props.increment,
});
```
> To fix it, use a second form of setState() that accepts a function rather than an object. That function will receive the previous state as the first argument, and the props at the time the update is applied as the second argument:
```
// Correct
this.setState((state, props) => ({
counter: state.counter + props.increment
}));
```
---
`_updateCellsToRender()` transitively calls many functions which will read directly from `this.props` or `this.state` instead of the value passed by the state updater. This intermittently fires invariant violations, when there is a mismatch.
This diff migrates all usages of `props` and `state` during state update to the values provied in `setState()`. To prevent future mismatch, and to provide better clarity on when it is safe to use `this.props`, `this.state`, I overrode `setState` to fire an invariant violation if it is accessed when it is unsafe to:
{F756963772}
Changelog:
[Internal][Changed] - Move Props to VirtualizedListProps
Reviewed By: genkikondo
Differential Revision: D38293587
fbshipit-source-id: 164fd4af7c370d905af53b0e9aafb3592d8659cc
Summary:
This diff is part of an overall stack, meant to fix incorrect usage of `setState()` in `VirtualizedList`, which triggers new invariant checks added in `VirtualizedList_EXPERIMENTAL`. See the stack summary below for more information on the broader change.
## Diff Summary
Remove `this.props` usage during state update where we can just use the props directly.
## Stack Summary
`VirtualizedList`'s component state is a set of cells to render. This state is set via the `setState()` class component API. The main "tick" function `VirtualizedList._updateCellsToRender()` calculates this new state using a combination of the current component state, and instance-local state like maps, measurement caches, etc.
From: https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous
---
> React may batch multiple setState() calls into a single update for performance. Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state. For example, this code may fail to update the counter:
```
// Wrong
this.setState({
counter: this.state.counter + this.props.increment,
});
```
> To fix it, use a second form of setState() that accepts a function rather than an object. That function will receive the previous state as the first argument, and the props at the time the update is applied as the second argument:
```
// Correct
this.setState((state, props) => ({
counter: state.counter + props.increment
}));
```
---
`_updateCellsToRender()` transitively calls many functions which will read directly from `this.props` or `this.state` instead of the value passed by the state updater. This intermittently fires invariant violations, when there is a mismatch.
This diff migrates all usages of `props` and `state` during state update to the values provied in `setState()`. To prevent future mismatch, and to provide better clarity on when it is safe to use `this.props`, `this.state`, I overrode `setState` to fire an invariant violation if it is accessed when it is unsafe to:
{F756963772}
Changelog:
[Internal][Fixed] - Remove _isVirtualizationDisabled()
Reviewed By: genkikondo
Differential Revision: D38293589
fbshipit-source-id: af18f867fc880d5363134fe0d6f985efaf8be6c5
Summary:
This diff is part of an overall stack, meant to fix incorrect usage of `setState()` in `VirtualizedList`, which triggers new invariant checks added in `VirtualizedList_EXPERIMENTAL`. See the stack summary below for more information on the broader change.
## Diff Summary
This moves public VirtualizedList types to a new file, shared between both `VirtualizedList`, and `VirtualizedList_EXPERIMENTAL`. This allows us to make public interface changes in a single place.
## Stack Summary
`VirtualizedList`'s component state is a set of cells to render. This state is set via the `setState()` class component API. The main "tick" function `VirtualizedList._updateCellsToRender()` calculates this new state using a combination of the current component state, and instance-local state like maps, measurement caches, etc.
From: https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous
---
> React may batch multiple setState() calls into a single update for performance. Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state. For example, this code may fail to update the counter:
```
// Wrong
this.setState({
counter: this.state.counter + this.props.increment,
});
```
> To fix it, use a second form of setState() that accepts a function rather than an object. That function will receive the previous state as the first argument, and the props at the time the update is applied as the second argument:
```
// Correct
this.setState((state, props) => ({
counter: state.counter + props.increment
}));
```
---
`_updateCellsToRender()` transitively calls many functions which will read directly from `this.props` or `this.state` instead of the value passed by the state updater. This intermittently fires invariant violations, when there is a mismatch.
This diff migrates all usages of `props` and `state` during state update to the values provied in `setState()`. To prevent future mismatch, and to provide better clarity on when it is safe to use `this.props`, `this.state`, I overrode `setState` to fire an invariant violation if it is accessed when it is unsafe to:
{F756963772}
Changelog:
[Internal][Changed] - Move Props to VirtualizedListProps
Reviewed By: genkikondo
Differential Revision: D38293585
fbshipit-source-id: 344d94466a2741ee67eb5754de5506eb3e265c5b
Summary:
This diff is part of an overall stack, meant to fix incorrect usage of `setState()` in `VirtualizedList`, which triggers new invariant checks added in `VirtualizedList_EXPERIMENTAL`. See the stack summary below for more information on the broader change.
## Diff Summary
Replace usages of `this.state` and `this.props` where we are already passed the newer revision of the state we want.
## Stack Summary
`VirtualizedList`'s component state is a set of cells to render. This state is set via the `setState()` class component API. The main "tick" function `VirtualizedList._updateCellsToRender()` calculates this new state using a combination of the current component state, and instance-local state like maps, measurement caches, etc.
From: https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous
---
> React may batch multiple setState() calls into a single update for performance. Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state. For example, this code may fail to update the counter:
```
// Wrong
this.setState({
counter: this.state.counter + this.props.increment,
});
```
> To fix it, use a second form of setState() that accepts a function rather than an object. That function will receive the previous state as the first argument, and the props at the time the update is applied as the second argument:
```
// Correct
this.setState((state, props) => ({
counter: state.counter + props.increment
}));
```
---
`_updateCellsToRender()` transitively calls many functions which will read directly from `this.props` or `this.state` instead of the value passed by the state updater. This intermittently fires invariant violations, when there is a mismatch.
This diff migrates all usages of `props` and `state` during state update to the values provied in `setState()`. To prevent future mismatch, and to provide better clarity on when it is safe to use `this.props`, `this.state`, I overrode `setState` to fire an invariant violation if it is accessed when it is unsafe to:
{F756963772}
Changelog:
[Internal][Fixed] - Remove bad usage in _adjustCellsAroundViewport()
Reviewed By: genkikondo
Differential Revision: D38293584
fbshipit-source-id: 807f36600d2fd82c87205195dd61956785bdbd2c
Summary:
VirtualizedList state is represented in terms of [first, last] ranges, where it is possible to express a zero-cell range by having [n, n-1]. This includes some awkward examples, like [0, -1] being valid.
CellRenderMask assumes `addCells` is called with at least one cell, with VirtualizedList previously guarding against adding the no cell case. This guard is present for adding main cell regions, but not for `_initialRenderRegion()`, which can be overridden to have a zero length as well.
This moves the `CellRenderMask` to be permissive of zero-length cell regions, and removes the caller guard.
Changelog:
[Internal][Fixed] - Allow empty cell ranges in CellRenderMask
Reviewed By: rshest
Differential Revision: D38184444
fbshipit-source-id: d2dadfdd9628b24f894126d63b1eb93f6387b877
Summary:
Existing code may pass negative values for `initialScrollIndex`, which the previous implemnentation handled gracefully. Handle the case gracefully in VirtualizedList_EXPERIMENTAL as well.
Changelog:
[Internal][Fixed] - Gracefully handle negative initialScrollIndex in VirtualizedList_EXPERIMENTAL
Reviewed By: rshest
Differential Revision: D38183625
fbshipit-source-id: 9aea91c4cf3ce2190d769f34ce728a109efc88d4
Summary:
If FlatList is passed non-array data it will return `undefined` as the result of `getItemCount()` to VirtualizedList. This change makes it return `0` instead, to signify there are no valid items to attempt to accces.
There are a set of invariants on properties passed to FlatList, to curb incorrect types at runtime, but there is existing code which runs into the condition.
Changelog:
[Internal][Fixed] - Guard FlatList getItemCount() against non-array data
Reviewed By: javache
Differential Revision: D38198351
fbshipit-source-id: 9efd0df7eeeba17078e2c838d470c4b0d621b9a0
Summary:
VirtualizedList_EXPERIMENTAL has a different flow signature from VirtualizedList. This does not cause an error in unit tests, which are untyped, but prevents injecting VirtualizedList_EXPERIMENTAL via the current API from flowtype. This diff updates the injection interface to allow a more relaxed type, validating safety at runtime.
Changelog:
[Internal][Changed] - Allow injecting looser VirtualizedList
Reviewed By: javache
Differential Revision: D38143682
fbshipit-source-id: 054bbc5092823f4e4413d69d3d72a7ecdd71a6a2
Summary:
I've noticed that `BackHandler.removeEventListener()` performs two same `indexOf()` calls on an array that is not changing. By removing extra `indexOf` we can slightly improve time complexity of `BackHandler.removeEventListener()` from O(2n) to O(n)
## Changelog
<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->
[Android] [Fixed] - Remove extra indexOf call in BackHandler.removeEventListener
Pull Request resolved: https://github.com/facebook/react-native/pull/34281
Test Plan:
1. Add the following code to any function component
```javascript
BackHandler.addEventListener('hardwareBackPress', () => true).remove();
```
2. Press on hardware back button
Expected result: Application closes
Reviewed By: dmitryrykun
Differential Revision: D38198510
Pulled By: javache
fbshipit-source-id: eab6a57689a536623138a4b3ebddbf9ba87d281f
Summary:
At the moment we are having a bug that whenever we hit a "Done" button in an input field, a value is not submitted back, so the users cannot complete their work. Here is an example:
https://pxl.cl/28xFq
To fix it, we call a textInputShouldSubmitOnReturn method on Accessory button click.
Changelog
[IOS][Fixed] - Fix keyboard accessory button not triggering onSubmitEditing
Reviewed By: dmitryrykun
Differential Revision: D38152974
fbshipit-source-id: fc026dffd641966cd3d342d95a56c43c71008036
Summary:
# This Change
https://github.com/react-native-community/discussions-and-proposals/pull/335 discussed a set of problems with VirtualizedList and focus. These were seen as severe externally for a11y on desktop. The issues center on users of keyboard and accessibility tools, where users expect to be able to move focus in an uninterrupted loop.
The design and implementation evolved to be a bit more general, and without any API-surface behavior changes. It was implemented and rolled out externally as a series of changes. The remaining changes that were not upstreamed into RN are rolled into https://github.com/facebook/react-native/pull/32646
This diff brings this change into the repo, as a separate copy of VirtualizedList, to measure its impact to guardrail metrics, without yet making it the default implementation. The intention is for this to be temporary, until there is confidence the implementation is correct.
## List Implementation (more on GitHub)
This change makes it possible to synchronously move native focus to arbitrary items in a VirtualizedList. This is implemented by switching component state to a sparse bitset. This was previously implemented and upstreamed as `CellRenderMask`.
A usage of this is added, to keep the last focused item rendered. This allows the focus loop to remain unbroken, when scrolling away, or tab loops which leave/re-enter the list.
VirtualizedList tracks the last focused cell through the capture phase of `onFocus`. It will keep the cell, and a viewport above and below the last focused cell rendered, to allow movement to it without blanking (without using too much memory).
## Experimentation Implementation
A mechanism is added to gate the change via VirtualizedListInjection, mirroring the approach taken for Switch with D27381306 (https://github.com/facebook/react-native/commit/683b825b327e7fa71e87e3d613cb9acd37c24288).
It allows VirtualizedList to delegate to a global override. It has a slight penalty to needing to import both modules, but means code which imports VirtualizedList directly is affected the changes.
Changelog:
[Internal][Added] - Add VirtualizedList_EXPERIMENTAL (CellRenderMask Usage)
Reviewed By: lunaleaps
Differential Revision: D38020408
fbshipit-source-id: ad0aaa6791f3f4455e3068502a2841f3ffb40b41
Summary:
This change is in preparation of adding a separate `VirtualizedList_EXPERIMENTAL` component.
Both the original, and experimental lists use `VirtualizedListContext`, which itself references back to the VirtualizedList class type. VirtualizedList private methods are currently included in the type system, and are called in other VirtualizedList code (see https://github.com/facebook/react-native/commit/b2f871a6fa9c92dd0712055384b9eca6d828e37d). This prevents Flow from seeing the two classes are compatible if "private" methods change.
My first attempt was to parameterize the context, to allow both `VirtualizedList`, and `VirtualizedList_EXPERIMENTAL` to use the same code without sacrificing type safety or adding further duplication. This added more complexity than it is worth, so I am instead loosening the type on VirtualizedListContext to pass around a more generic handle.
Changelog:
[Internal][Changed] - Allow VirtualizedListContext to support different component type
Reviewed By: javache
Differential Revision: D38017086
fbshipit-source-id: 91e8f6ab2591d3ae9b7f9263711b4a39b78f68e0
Summary:
The `NSMutableAttributedString` was initialized with the same backing store as the cached attributed string on the shadow queue (background thread), but then passed to the main thread and ultimately the JS thread.
This explicitly copies the mutable attributed string into an immutable one on the shadow thread before passed off to other threads, which hopefully will address the `convertIdToFollyDynamic` crash that always includes `RCTBaseTextInputShadowView` touching an attributed string on the shadow queue in the trace.
Changelog:
[iOS][Fixed] - Possible fix for convertIdToFollyDynamic crash in RCTBaseTextInputView and RCTEventDispatcher
Reviewed By: sammy-SC
Differential Revision: D38133150
fbshipit-source-id: f371da5d17a32c3341287cd3e9730b31a98495f9
Summary:
Add capture-phase focus events to the type system, for use in the refactored VirtualizedList https://github.com/facebook/react-native/pull/32646/files
Tracking the last focused child is done via focus events. Focus events are bubbling (vs direct events like onLayout), and are given both a "capture" phase, and "bubbling phase", like DOM events on the web. https://stackoverflow.com/questions/4616694/what-is-event-bubbling-and-capturing
The VirtualizedList change wants to know if a child will receive focus. This is not possible to reliably capture in the bubbling phase, since a child may stop propagation.
See https://github.com/react-native-community/discussions-and-proposals/pull/335#discussion_r584851337 for some discussion with Scott Kyle about this issue back in the day
This is done by convention in React by adding a "capture" variant of the `onXXX` method. For all platforms I've seen with focus events, these map the `topFocus` native event to `onFocus` for bubbling phase, and `onFocusCapture` for capture phase. See https://reactjs.org/docs/events.html#supported-events
Changelog:
[General][Added] - Add types for onFocusCapture/onBlurCapture
Reviewed By: javache
Differential Revision: D38013861
fbshipit-source-id: 7bda22e1a4d5e36ac5e34e804abf6fb318a41baf
Summary:
We are already returning the `remove` function, and the `removeEventListener` method has been removed in this PR: https://github.com/facebook/react-native/issues/33580. So I believe this comment is now outdated and no longer relevant.
## Changelog
<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->
[Internal] [Removed] - Remove outdated TODO in AppState
Pull Request resolved: https://github.com/facebook/react-native/pull/34264
Reviewed By: dmitryrykun
Differential Revision: D38120344
Pulled By: GijsWeterings
fbshipit-source-id: c6c4d42f5b631a67bb6ad49c14df1a772f1cc71b
Summary:
A crash encountered in react-native-macOS is very similar to one fixed by https://github.com/microsoft/react-native-macos/pull/489#discussion_r451789471 (see discussion), and it's possible this `replacement` string also suffers from sharing the same backing store as the attributed string (maybe only when the range encompasses the entire string?) and therefore should be copied as well.
Changelog:
[iOS][Fixed] - Possible fix for convertIdToFollyDynamic crash in RCTBaseTextInputView and RCTEventDispatcher
Reviewed By: sammy-SC
Differential Revision: D38064551
fbshipit-source-id: 9c15f2a980155ab3cbb3fde79fcb93b24ee2091a
Summary:
This method assumes a semicolon existed before the closing bracket (`>`), but only does on iOS. This instead puts the content before the closing bracket, which is always there on both platforms.
Changelog:
[macOS][Fixed] - Fix exception thrown by [RCTTextView description] on macOS
Reviewed By: sammy-SC
Differential Revision: D38074642
fbshipit-source-id: f46d15c2bf2d966d1c1430568f083e4d501d4b40
Summary:
Currently, with the Alert API on iOS, the only way to bold one of the buttons is by setting the style to "cancel". This has the side-effect of moving it to the left. The underlying UIKit API has a way of setting a "preferred" button, which does not have this negative side-effect, so this PR wires this up.
See preferredAction on UIAlertController https://developer.apple.com/documentation/uikit/uialertcontroller/
Docs PR: https://github.com/facebook/react-native-website/pull/2839
## Changelog
[iOS] [Added] - Support setting an Alert button as "preferred", to emphasize it without needing to set it as a "cancel" button.
Pull Request resolved: https://github.com/facebook/react-native/pull/32538
Test Plan:
I ran the RNTesterPods app and added an example. It has a button styled with "preferred" and another with "cancel", to demonstrate that the "preferred" button takes emphasis over the "cancel" button.

Luna:
* Also tested this on Catalyst
{F754959632}
Reviewed By: sammy-SC
Differential Revision: D34357811
Pulled By: lunaleaps
fbshipit-source-id: 3d860702c49cb219f950904ae0b9fabef03b5588
Summary:
Log whether bridgeless mode is enabled or not when calling into a JavaScript module method fails.
We are seeing a surge of these crashes in MessageQueue.js bridgeless mode. This temporary log will help us drill down into the issue.
Changelog: [Internal]
Created from CodeHub with https://fburl.com/edit-in-codehub
This should not mess with the sitevar overrides.
These are the two diffs where we mapped the venice and bridge errors to the same mid: D36649249, D36649249.
Reviewed By: fkgozali
Differential Revision: D37898744
fbshipit-source-id: 0ab337c8c0d73bd70c4756a16b8ece8ba8730c47
Summary:
Now that [exact_empty_objects has been enabled](https://fb.workplace.com/groups/flowlang/posts/1092665251339137), we can codemod `{...null}` to `{}` - they are now equivalent.
1) Run my one-off jscodeshift codemod
2) `scripts/flow/tool update-suppressions .` (as some suppressions move around due to the change)
drop-conflicts
Reviewed By: bradzacher
Differential Revision: D37834078
fbshipit-source-id: 6bf4913910e5597e5dd9d5161cd35deece6a7581
Summary:
A layout-impacting style change will trigger a layout effect hook within `TextInput`. This hook fires a ViewManager command to set the text input based on the known JS value: https://github.com/facebook/react-native/blob/d82cd3cbce1597512bb2868fde49b5b3850892a0/Libraries/Components/TextInput/TextInput.js#L1009
The JS value is determined using `value` if set, falling back to `defaultValue`. If a component uses `TextInput` as an uncontrolled component, and does not set this value, the command wipes text input back to the default value. This does not happen on re-render of the JS side, despite setting text prop, since the underlying native property never changes/triggers a rerender.
This change alters the logic to prefer `lastNativeText` instead of `defaultValue` when available, to retain the updated `TextInput` content on relayout.
Reviewed By: javache
Differential Revision: D37801394
fbshipit-source-id: d56c719d56bebac64553c731ce9fca8efc7feae9
Summary:
Ahead of enabling the `exact_empty_objects` option, suppress errors so that actually enabling the option is easier. We can do this without enabling the option by codemoding `{}` to `{...null}` in files that have errors.
Process:
1) Get list of files with errors when enabling the option
2) Codemod `{}` to `{...null}` in those files
3) Suppress resulting errors
4) Land diff with `drop-conflicts` flag
5) Announce and enable option (with many fewer files to edit)
6) Codemod all `{...null}` to `{}`
drop-conflicts
We are working on making the empty object literal `{}` have the type `{}` - i.e. exact empty object - rather than being unsealed.
More info in these posts: https://fb.workplace.com/groups/flowlang/posts/903386663600331, https://fb.workplace.com/groups/floweng/posts/8626146484100557
Reviewed By: pieterv
Differential Revision: D37731004
fbshipit-source-id: a9305859ba4e8adbdb8ae8feff3ec8a2f07ed236
Summary: Changelog: [Internal] - We can now remove the '2' suffix as we had an internal implementation that was not truly aligned with W3C pointers but used the same name. We have aligned the internal types to match w3c so we can now remove the suffix that differentiates them.
Reviewed By: vincentriemer
Differential Revision: D37545813
fbshipit-source-id: 6f2336ae9e314066c340161113268c1f28621a71
Summary:
```js
async () => {
let blobs = [];
for (let i = 0; i < 4; i++) {
const res = await fetch();
blobs = [...blobs, await res.blob()]
}
const blob = new Blob(blobs); // <<<<<<<<<<<<<<< a
return await new Promise((resolve, reject) => {
const fileReader = new FileReader();
fileReader.onload = async () => {
await RNFS.writeFile(destPath, (fileReader.result as string).split(',')[1], 'base64');
resolve(destPath);
};
fileReader.onabort = () => {
reject('');
};
fileReader.onerror = (event) => {
reject('');
};
fileReader.readAsDataURL(blob); // <<<<<<<<<<<<<<< b
});
}
```
Sometime `fileReader.readAsDataURL` is unable to get blob from the dictionary after `new Blob(blobs)` and then reject with `Unable to resolve data for blob: blobId` in iOS or `The specified blob is invalid` in android. Because line `a` and `b` can be run in different thread. `new Blob([])` is in progress and `fileReader.readAsDataURL` accesses the blob dictionary ahead of the blob creation.
The expected behaviour is it should finish new Blob([]) first and then readAsDataURL(blob)
To fix that, there should be a lock inside the method `createFromParts`. For iOS, It needs to be a recursive_mutex to allow same thread to acquire lock
## Changelog
<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
https://github.com/facebook/react-native/wiki/Changelog
-->
[iOS] [Fixed] - fix the race condition when calling readAsDataURL after new Blob(blobs)
Pull Request resolved: https://github.com/facebook/react-native/pull/34096
Reviewed By: cipolleschi
Differential Revision: D37514981
Pulled By: javache
fbshipit-source-id: 4bf84ece99871276ecaa5aa1849b9145ff44dbf4
Summary:
`InputAccessoryView` works fine on iOS, but crashes on Android - you can see that by using an Android device on the [Expo Snack from the official doc](https://reactnative.dev/docs/inputaccessoryview).
It forces the developer not to render the component on Android, which is usually good, but other components have implemented other, safer ways to deal with incompatibility issues.
I am of course open to discussion about this change, as well as other implementation ideas.
## Changelog
[Android] [Fixed] - Fix InputAccessoryView crash on Android
Pull Request resolved: https://github.com/facebook/react-native/pull/33803
Test Plan:
`yarn test` gives out the following output:

Reviewed By: cipolleschi
Differential Revision: D37215394
Pulled By: cortinico
fbshipit-source-id: 66c4401f7c61b745ea893969d69c8dde3e5afb03
Summary:
Removes the `isTVOS` check, which just duplicated and returned the `isTV` check anyway.
## Changelog
<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
https://github.com/facebook/react-native/wiki/Changelog
-->
[General] [Removed] - Remove deprecated `isTVOS` constant.
Pull Request resolved: https://github.com/facebook/react-native/pull/34071
Test Plan: Run against CI, and apply changes as needed.
Reviewed By: cipolleschi
Differential Revision: D37434978
Pulled By: cortinico
fbshipit-source-id: 2b38253125251b0ce28cf10c88471d8f16704999
Summary: Add annotations to function parameters required for Flow's Local Type Inference project. This codemod prepares the codebase to match Flow's new typechecking algorithm. The new algorithm will make Flow more reliable and predictable.
Reviewed By: bradzacher
Differential Revision: D37388949
fbshipit-source-id: cdcbc98035ce9b6994842005ea46df42de54f9b8
Summary: Add annotations to function parameters required for Flow's Local Type Inference project. This codemod prepares the codebase to match Flow's new typechecking algorithm. The new algorithm will make Flow more reliable and predicatable.
Reviewed By: bradzacher
Differential Revision: D37363351
fbshipit-source-id: a9d3df7db6f9d094ac2ce81aae1f3ab4f62b243a
Summary: Add annotations to function parameters required for Flow's Local Type Inference project. This codemod prepares the codebase to match Flow's new typechecking algorithm. The new algorithm will make Flow more reliable and predicatable.
Reviewed By: evanyeung
Differential Revision: D37353648
fbshipit-source-id: e5a0c685ced85a8ff353d578b373f836b376bb28
Summary: Add annotations to function parameters required for Flow's Local Type Inference project. This codemod prepares the codebase to match Flow's new typechecking algorithm. The new algorithm will make Flow more reliable and predicatable.
Reviewed By: evanyeung
Differential Revision: D37360113
fbshipit-source-id: 870bcfe680542b3861fefbaf372db0ae8b32cbf3
Summary:
Bumping RTC-Folly version used to address CVE-2022-24440.
## Changelog
<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
https://github.com/facebook/react-native/wiki/Changelog
-->
[General][Security] - Bump RTC-Folly to 2021-07-22
Pull Request resolved: https://github.com/facebook/react-native/pull/33841
Reviewed By: Andjeliko, philIip
Differential Revision: D36425598
Pulled By: cortinico
fbshipit-source-id: d38c5f020dbecf794b10f12ed2da30e1825071af