mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
VirtualizedList: Migrate to React.Context
Summary: Migrates `VirtualizedList` off legacy context by creating `VirtualizedListContext`. Changelog: [General][Changed] - Migrated `virtualizedList` legacy context to `React.Context`. Reviewed By: TheSavior Differential Revision: D21370882 fbshipit-source-id: 2fa99ee0bc0e6b747a2d3fe7c66ee402c6b9c5af
This commit is contained in:
committed by
Facebook GitHub Bot
parent
9cdc19a936
commit
7bd694fc6f
@@ -13,7 +13,6 @@
|
||||
const Batchinator = require('../Interaction/Batchinator');
|
||||
const FillRateHelper = require('./FillRateHelper');
|
||||
const PropTypes = require('prop-types');
|
||||
const React = require('react');
|
||||
const ReactNative = require('../Renderer/shims/ReactNative');
|
||||
const RefreshControl = require('../Components/RefreshControl/RefreshControl');
|
||||
const ScrollView = require('../Components/ScrollView/ScrollView');
|
||||
@@ -28,6 +27,7 @@ const warning = require('fbjs/lib/warning');
|
||||
|
||||
const {computeWindowedRenderLimits} = require('./VirtualizeUtils');
|
||||
|
||||
import * as React from 'react';
|
||||
import type {ScrollResponderType} from '../Components/ScrollView/ScrollView';
|
||||
import type {ViewStyleProp} from '../StyleSheet/StyleSheet';
|
||||
import type {
|
||||
@@ -35,6 +35,13 @@ import type {
|
||||
ViewToken,
|
||||
ViewabilityConfigCallbackPair,
|
||||
} from './ViewabilityHelper';
|
||||
import {
|
||||
VirtualizedListCellContextProvider,
|
||||
VirtualizedListContext,
|
||||
VirtualizedListContextProvider,
|
||||
type ChildListState,
|
||||
type ListDebugInfo,
|
||||
} from './VirtualizedListContext.js';
|
||||
|
||||
type Item = any;
|
||||
|
||||
@@ -315,37 +322,9 @@ type DefaultProps = {|
|
||||
let _usedIndexForKey = false;
|
||||
let _keylessItemComponentName: string = '';
|
||||
|
||||
type Frame = {
|
||||
offset: number,
|
||||
length: number,
|
||||
index: number,
|
||||
inLayout: boolean,
|
||||
...
|
||||
};
|
||||
|
||||
type ChildListState = {
|
||||
first: number,
|
||||
last: number,
|
||||
frames: {[key: number]: Frame, ...},
|
||||
...
|
||||
};
|
||||
|
||||
type State = {
|
||||
first: number,
|
||||
last: number,
|
||||
...
|
||||
};
|
||||
|
||||
// Data propagated through nested lists (regardless of orientation) that is
|
||||
// useful for producing diagnostics for usage errors involving nesting (e.g
|
||||
// missing/duplicate keys).
|
||||
type ListDebugInfo = {
|
||||
cellKey: string,
|
||||
listKey: string,
|
||||
parent: ?ListDebugInfo,
|
||||
// We include all ancestors regardless of orientation, so this is not always
|
||||
// identical to the child's orientation.
|
||||
horizontal: boolean,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -377,7 +356,7 @@ type ListDebugInfo = {
|
||||
*
|
||||
*/
|
||||
class VirtualizedList extends React.PureComponent<Props, State> {
|
||||
props: Props;
|
||||
static contextType: typeof VirtualizedListContext = VirtualizedListContext;
|
||||
|
||||
// scrollToEnd may be janky without getItemLayout prop
|
||||
scrollToEnd(params?: ?{animated?: ?boolean, ...}) {
|
||||
@@ -582,111 +561,8 @@ class VirtualizedList extends React.PureComponent<Props, State> {
|
||||
windowSize: 21, // multiples of length
|
||||
};
|
||||
|
||||
static contextTypes:
|
||||
| any
|
||||
| {|
|
||||
virtualizedCell: {|
|
||||
cellKey: React$PropType$Primitive<string>,
|
||||
|},
|
||||
virtualizedList: {|
|
||||
getScrollMetrics: React$PropType$Primitive<Function>,
|
||||
horizontal: React$PropType$Primitive<boolean>,
|
||||
getOutermostParentListRef: React$PropType$Primitive<Function>,
|
||||
getNestedChildState: React$PropType$Primitive<Function>,
|
||||
registerAsNestedChild: React$PropType$Primitive<Function>,
|
||||
unregisterAsNestedChild: React$PropType$Primitive<Function>,
|
||||
debugInfo: {|
|
||||
listKey: React$PropType$Primitive<string>,
|
||||
cellKey: React$PropType$Primitive<string>,
|
||||
|},
|
||||
|},
|
||||
|} = {
|
||||
virtualizedCell: PropTypes.shape({
|
||||
cellKey: PropTypes.string,
|
||||
}),
|
||||
virtualizedList: PropTypes.shape({
|
||||
getScrollMetrics: PropTypes.func,
|
||||
horizontal: PropTypes.bool,
|
||||
getOutermostParentListRef: PropTypes.func,
|
||||
getNestedChildState: PropTypes.func,
|
||||
registerAsNestedChild: PropTypes.func,
|
||||
unregisterAsNestedChild: PropTypes.func,
|
||||
debugInfo: PropTypes.shape({
|
||||
listKey: PropTypes.string,
|
||||
cellKey: PropTypes.string,
|
||||
}),
|
||||
}),
|
||||
};
|
||||
|
||||
static childContextTypes:
|
||||
| any
|
||||
| {|
|
||||
getScrollMetrics: React$PropType$Primitive<Function>,
|
||||
horizontal: React$PropType$Primitive<boolean>,
|
||||
getOutermostParentListRef: React$PropType$Primitive<Function>,
|
||||
getNestedChildState: React$PropType$Primitive<Function>,
|
||||
registerAsNestedChild: React$PropType$Primitive<Function>,
|
||||
unregisterAsNestedChild: React$PropType$Primitive<Function>,
|
||||
|} = {
|
||||
virtualizedList: PropTypes.shape({
|
||||
getScrollMetrics: PropTypes.func,
|
||||
horizontal: PropTypes.bool,
|
||||
getOutermostParentListRef: PropTypes.func,
|
||||
getNestedChildState: PropTypes.func,
|
||||
registerAsNestedChild: PropTypes.func,
|
||||
unregisterAsNestedChild: PropTypes.func,
|
||||
}),
|
||||
};
|
||||
|
||||
getChildContext(): {|
|
||||
virtualizedList: {
|
||||
getScrollMetrics: () => {
|
||||
contentLength: number,
|
||||
dOffset: number,
|
||||
dt: number,
|
||||
offset: number,
|
||||
timestamp: number,
|
||||
velocity: number,
|
||||
visibleLength: number,
|
||||
...
|
||||
},
|
||||
horizontal: ?boolean,
|
||||
getOutermostParentListRef: Function,
|
||||
getNestedChildState: string => ?ChildListState,
|
||||
registerAsNestedChild: ({
|
||||
cellKey: string,
|
||||
key: string,
|
||||
ref: VirtualizedList,
|
||||
parentDebugInfo: ListDebugInfo,
|
||||
...
|
||||
}) => ?ChildListState,
|
||||
unregisterAsNestedChild: ({
|
||||
key: string,
|
||||
state: ChildListState,
|
||||
...
|
||||
}) => void,
|
||||
debugInfo: ListDebugInfo,
|
||||
...
|
||||
},
|
||||
|} {
|
||||
return {
|
||||
virtualizedList: {
|
||||
getScrollMetrics: this._getScrollMetrics,
|
||||
horizontal: this.props.horizontal,
|
||||
getOutermostParentListRef: this._getOutermostParentListRef,
|
||||
getNestedChildState: this._getNestedChildState,
|
||||
registerAsNestedChild: this._registerAsNestedChild,
|
||||
unregisterAsNestedChild: this._unregisterAsNestedChild,
|
||||
debugInfo: this._getDebugInfo(),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
_getCellKey(): string {
|
||||
return (
|
||||
(this.context.virtualizedCell && this.context.virtualizedCell.cellKey) ||
|
||||
'rootList'
|
||||
);
|
||||
return this.context?.cellKey || 'rootList';
|
||||
}
|
||||
|
||||
_getListKey(): string {
|
||||
@@ -698,9 +574,7 @@ class VirtualizedList extends React.PureComponent<Props, State> {
|
||||
listKey: this._getListKey(),
|
||||
cellKey: this._getCellKey(),
|
||||
horizontal: !!this.props.horizontal,
|
||||
parent: this.context.virtualizedList
|
||||
? this.context.virtualizedList.debugInfo
|
||||
: null,
|
||||
parent: this.context?.debugInfo,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -714,7 +588,7 @@ class VirtualizedList extends React.PureComponent<Props, State> {
|
||||
|
||||
_getOutermostParentListRef = () => {
|
||||
if (this._isNestedWithSameOrientation()) {
|
||||
return this.context.virtualizedList.getOutermostParentListRef();
|
||||
return this.context.getOutermostParentListRef();
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
@@ -774,8 +648,8 @@ class VirtualizedList extends React.PureComponent<Props, State> {
|
||||
|
||||
state: State;
|
||||
|
||||
constructor(props: Props, context: Object) {
|
||||
super(props, context);
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
invariant(
|
||||
// $FlowFixMe
|
||||
!props.onScroll || !props.onScroll.__isNative,
|
||||
@@ -818,9 +692,7 @@ class VirtualizedList extends React.PureComponent<Props, State> {
|
||||
};
|
||||
|
||||
if (this._isNestedWithSameOrientation()) {
|
||||
const storedState = this.context.virtualizedList.getNestedChildState(
|
||||
this._getListKey(),
|
||||
);
|
||||
const storedState = this.context.getNestedChildState(this._getListKey());
|
||||
if (storedState) {
|
||||
initialState = storedState;
|
||||
this.state = storedState;
|
||||
@@ -833,7 +705,7 @@ class VirtualizedList extends React.PureComponent<Props, State> {
|
||||
|
||||
componentDidMount() {
|
||||
if (this._isNestedWithSameOrientation()) {
|
||||
this.context.virtualizedList.registerAsNestedChild({
|
||||
this.context.registerAsNestedChild({
|
||||
cellKey: this._getCellKey(),
|
||||
key: this._getListKey(),
|
||||
ref: this,
|
||||
@@ -841,14 +713,14 @@ class VirtualizedList extends React.PureComponent<Props, State> {
|
||||
// the parent's props. This is why we explicitly propagate debugInfo
|
||||
// "down" via context and "up" again via this method call on the
|
||||
// parent.
|
||||
parentDebugInfo: this.context.virtualizedList.debugInfo,
|
||||
parentDebugInfo: this.context.debugInfo,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this._isNestedWithSameOrientation()) {
|
||||
this.context.virtualizedList.unregisterAsNestedChild({
|
||||
this.context.unregisterAsNestedChild({
|
||||
key: this._getListKey(),
|
||||
state: {
|
||||
first: this.state.first,
|
||||
@@ -943,7 +815,7 @@ class VirtualizedList extends React.PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
_isNestedWithSameOrientation(): boolean {
|
||||
const nestedContext = this.context.virtualizedList;
|
||||
const nestedContext = this.context;
|
||||
return !!(
|
||||
nestedContext && !!nestedContext.horizontal === !!this.props.horizontal
|
||||
);
|
||||
@@ -984,7 +856,7 @@ class VirtualizedList extends React.PureComponent<Props, State> {
|
||||
<ListHeaderComponent />
|
||||
);
|
||||
cells.push(
|
||||
<VirtualizedCellWrapper
|
||||
<VirtualizedListCellContextProvider
|
||||
cellKey={this._getCellKey() + '-header'}
|
||||
key="$header">
|
||||
<View
|
||||
@@ -998,7 +870,7 @@ class VirtualizedList extends React.PureComponent<Props, State> {
|
||||
element
|
||||
}
|
||||
</View>
|
||||
</VirtualizedCellWrapper>,
|
||||
</VirtualizedListCellContextProvider>,
|
||||
);
|
||||
}
|
||||
const itemCount = this.props.getItemCount(data);
|
||||
@@ -1139,7 +1011,7 @@ class VirtualizedList extends React.PureComponent<Props, State> {
|
||||
<ListFooterComponent />
|
||||
);
|
||||
cells.push(
|
||||
<VirtualizedCellWrapper
|
||||
<VirtualizedListCellContextProvider
|
||||
cellKey={this._getFooterCellKey()}
|
||||
key="$footer">
|
||||
<View
|
||||
@@ -1153,7 +1025,7 @@ class VirtualizedList extends React.PureComponent<Props, State> {
|
||||
element
|
||||
}
|
||||
</View>
|
||||
</VirtualizedCellWrapper>,
|
||||
</VirtualizedListCellContextProvider>,
|
||||
);
|
||||
}
|
||||
const scrollProps = {
|
||||
@@ -1178,14 +1050,29 @@ class VirtualizedList extends React.PureComponent<Props, State> {
|
||||
this._hasMore =
|
||||
this.state.last < this.props.getItemCount(this.props.data) - 1;
|
||||
|
||||
const innerRet = React.cloneElement(
|
||||
(this.props.renderScrollComponent || this._defaultRenderScrollComponent)(
|
||||
scrollProps,
|
||||
),
|
||||
{
|
||||
ref: this._captureScrollRef,
|
||||
},
|
||||
cells,
|
||||
const innerRet = (
|
||||
<VirtualizedListContextProvider
|
||||
value={{
|
||||
cellKey: null,
|
||||
getScrollMetrics: this._getScrollMetrics,
|
||||
horizontal: this.props.horizontal,
|
||||
getOutermostParentListRef: this._getOutermostParentListRef,
|
||||
getNestedChildState: this._getNestedChildState,
|
||||
registerAsNestedChild: this._registerAsNestedChild,
|
||||
unregisterAsNestedChild: this._unregisterAsNestedChild,
|
||||
debugInfo: this._getDebugInfo(),
|
||||
}}>
|
||||
{React.cloneElement(
|
||||
(
|
||||
this.props.renderScrollComponent ||
|
||||
this._defaultRenderScrollComponent
|
||||
)(scrollProps),
|
||||
{
|
||||
ref: this._captureScrollRef,
|
||||
},
|
||||
cells,
|
||||
)}
|
||||
</VirtualizedListContextProvider>
|
||||
);
|
||||
let ret = innerRet;
|
||||
if (__DEV__) {
|
||||
@@ -1196,7 +1083,7 @@ class VirtualizedList extends React.PureComponent<Props, State> {
|
||||
scrollContext != null &&
|
||||
!scrollContext.horizontal === !this.props.horizontal &&
|
||||
!this._hasWarned.nesting &&
|
||||
this.context.virtualizedList == null
|
||||
this.context == null
|
||||
) {
|
||||
// TODO (T46547044): use React.warn once 16.9 is sync'd: https://github.com/facebook/react/pull/15170
|
||||
console.warn(
|
||||
@@ -1401,7 +1288,7 @@ class VirtualizedList extends React.PureComponent<Props, State> {
|
||||
// We are assuming that getOutermostParentListRef().getScrollRef()
|
||||
// is a non-null reference to a ScrollView
|
||||
this._scrollRef.measureLayout(
|
||||
this.context.virtualizedList.getOutermostParentListRef().getScrollRef(),
|
||||
this.context.getOutermostParentListRef().getScrollRef(),
|
||||
(x, y, width, height) => {
|
||||
this._offsetFromParentVirtualizedList = this._selectOffset({x, y});
|
||||
this._scrollMetrics.contentLength = this._selectLength({
|
||||
@@ -1409,7 +1296,7 @@ class VirtualizedList extends React.PureComponent<Props, State> {
|
||||
height,
|
||||
});
|
||||
const scrollMetrics = this._convertParentScrollMetrics(
|
||||
this.context.virtualizedList.getScrollMetrics(),
|
||||
this.context.getScrollMetrics(),
|
||||
);
|
||||
this._scrollMetrics.visibleLength = scrollMetrics.visibleLength;
|
||||
this._scrollMetrics.offset = scrollMetrics.offset;
|
||||
@@ -1988,12 +1875,6 @@ class CellRenderer extends React.Component<
|
||||
},
|
||||
};
|
||||
|
||||
static childContextTypes = {
|
||||
virtualizedCell: PropTypes.shape({
|
||||
cellKey: PropTypes.string,
|
||||
}),
|
||||
};
|
||||
|
||||
static getDerivedStateFromProps(
|
||||
props: CellRendererProps,
|
||||
prevState: CellRendererState,
|
||||
@@ -2006,14 +1887,6 @@ class CellRenderer extends React.Component<
|
||||
};
|
||||
}
|
||||
|
||||
getChildContext() {
|
||||
return {
|
||||
virtualizedCell: {
|
||||
cellKey: this.props.cellKey,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// TODO: consider factoring separator stuff out of VirtualizedList into FlatList since it's not
|
||||
// reused by SectionList and we can keep VirtualizedList simpler.
|
||||
_separators = {
|
||||
@@ -2119,18 +1992,15 @@ class CellRenderer extends React.Component<
|
||||
: horizontal
|
||||
? [styles.row, inversionStyle]
|
||||
: inversionStyle;
|
||||
if (!CellRendererComponent) {
|
||||
return (
|
||||
/* $FlowFixMe(>=0.89.0 site=react_native_fb) This comment suppresses an
|
||||
* error found when Flow v0.89 was deployed. To see the error, delete
|
||||
* this comment and run Flow. */
|
||||
<View style={cellStyle} onLayout={onLayout}>
|
||||
{element}
|
||||
{itemSeparator}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
return (
|
||||
const result = !CellRendererComponent ? (
|
||||
/* $FlowFixMe(>=0.89.0 site=react_native_fb) This comment suppresses an
|
||||
* error found when Flow v0.89 was deployed. To see the error, delete
|
||||
* this comment and run Flow. */
|
||||
<View style={cellStyle} onLayout={onLayout}>
|
||||
{element}
|
||||
{itemSeparator}
|
||||
</View>
|
||||
) : (
|
||||
<CellRendererComponent
|
||||
{...this.props}
|
||||
style={cellStyle}
|
||||
@@ -2139,30 +2009,12 @@ class CellRenderer extends React.Component<
|
||||
{itemSeparator}
|
||||
</CellRendererComponent>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class VirtualizedCellWrapper extends React.Component<{
|
||||
cellKey: string,
|
||||
children: React.Node,
|
||||
...
|
||||
}> {
|
||||
static childContextTypes = {
|
||||
virtualizedCell: PropTypes.shape({
|
||||
cellKey: PropTypes.string,
|
||||
}),
|
||||
};
|
||||
|
||||
getChildContext() {
|
||||
return {
|
||||
virtualizedCell: {
|
||||
cellKey: this.props.cellKey,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
return this.props.children;
|
||||
return (
|
||||
<VirtualizedListCellContextProvider cellKey={this.props.cellKey}>
|
||||
{result}
|
||||
</VirtualizedListCellContextProvider>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @flow strict-local
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import type VirtualizedList from './VirtualizedList.js';
|
||||
import * as React from 'react';
|
||||
import {useMemo, useContext} from 'react';
|
||||
|
||||
type Frame = $ReadOnly<{
|
||||
offset: number,
|
||||
length: number,
|
||||
index: number,
|
||||
inLayout: boolean,
|
||||
}>;
|
||||
|
||||
export type ChildListState = $ReadOnly<{
|
||||
first: number,
|
||||
last: number,
|
||||
frames: {[key: number]: Frame},
|
||||
}>;
|
||||
|
||||
// Data propagated through nested lists (regardless of orientation) that is
|
||||
// useful for producing diagnostics for usage errors involving nesting (e.g
|
||||
// missing/duplicate keys).
|
||||
export type ListDebugInfo = $ReadOnly<{
|
||||
cellKey: string,
|
||||
listKey: string,
|
||||
parent: ?ListDebugInfo,
|
||||
// We include all ancestors regardless of orientation, so this is not always
|
||||
// identical to the child's orientation.
|
||||
horizontal: boolean,
|
||||
}>;
|
||||
|
||||
type Context = $ReadOnly<{
|
||||
cellKey: ?string,
|
||||
getScrollMetrics: () => {
|
||||
contentLength: number,
|
||||
dOffset: number,
|
||||
dt: number,
|
||||
offset: number,
|
||||
timestamp: number,
|
||||
velocity: number,
|
||||
visibleLength: number,
|
||||
},
|
||||
horizontal: ?boolean,
|
||||
getOutermostParentListRef: () => VirtualizedList,
|
||||
getNestedChildState: string => ?ChildListState,
|
||||
registerAsNestedChild: ({
|
||||
cellKey: string,
|
||||
key: string,
|
||||
ref: VirtualizedList,
|
||||
parentDebugInfo: ListDebugInfo,
|
||||
}) => ?ChildListState,
|
||||
unregisterAsNestedChild: ({
|
||||
key: string,
|
||||
state: ChildListState,
|
||||
}) => void,
|
||||
debugInfo: ListDebugInfo,
|
||||
}>;
|
||||
|
||||
export const VirtualizedListContext: React.Context<?Context> = React.createContext(
|
||||
null,
|
||||
);
|
||||
|
||||
/**
|
||||
* Resets the context. Intended for use by portal-like components (e.g. Modal).
|
||||
*/
|
||||
export function VirtualizedListContextResetter({
|
||||
children,
|
||||
}: {
|
||||
children: React.Node,
|
||||
}): React.Node {
|
||||
return (
|
||||
<VirtualizedListContext.Provider value={null}>
|
||||
{children}
|
||||
</VirtualizedListContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the context with memoization. Intended to be used by `VirtualizedList`.
|
||||
*/
|
||||
export function VirtualizedListContextProvider({
|
||||
children,
|
||||
value,
|
||||
}: {
|
||||
children: React.Node,
|
||||
value: Context,
|
||||
}): React.Node {
|
||||
// Avoid setting a newly created context object if the values are identical.
|
||||
const context = useMemo(
|
||||
() => ({
|
||||
cellKey: null,
|
||||
getScrollMetrics: value.getScrollMetrics,
|
||||
horizontal: value.horizontal,
|
||||
getOutermostParentListRef: value.getOutermostParentListRef,
|
||||
getNestedChildState: value.getNestedChildState,
|
||||
registerAsNestedChild: value.registerAsNestedChild,
|
||||
unregisterAsNestedChild: value.unregisterAsNestedChild,
|
||||
debugInfo: {
|
||||
cellKey: value.debugInfo.cellKey,
|
||||
horizontal: value.debugInfo.horizontal,
|
||||
listKey: value.debugInfo.listKey,
|
||||
parent: value.debugInfo.parent,
|
||||
},
|
||||
}),
|
||||
[
|
||||
value.getScrollMetrics,
|
||||
value.horizontal,
|
||||
value.getOutermostParentListRef,
|
||||
value.getNestedChildState,
|
||||
value.registerAsNestedChild,
|
||||
value.unregisterAsNestedChild,
|
||||
value.debugInfo.cellKey,
|
||||
value.debugInfo.horizontal,
|
||||
value.debugInfo.listKey,
|
||||
value.debugInfo.parent,
|
||||
],
|
||||
);
|
||||
return (
|
||||
<VirtualizedListContext.Provider value={context}>
|
||||
{children}
|
||||
</VirtualizedListContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the `cellKey`. Intended to be used by `VirtualizedList` for each cell.
|
||||
*/
|
||||
export function VirtualizedListCellContextProvider({
|
||||
cellKey,
|
||||
children,
|
||||
}: {
|
||||
cellKey: string,
|
||||
children: React.Node,
|
||||
}): React.Node {
|
||||
const context = useContext(VirtualizedListContext);
|
||||
return (
|
||||
<VirtualizedListContext.Provider
|
||||
value={context == null ? null : {...context, cellKey}}>
|
||||
{children}
|
||||
</VirtualizedListContext.Provider>
|
||||
);
|
||||
}
|
||||
+11
-19
@@ -22,6 +22,8 @@ import type {ViewProps} from '../Components/View/ViewPropTypes';
|
||||
import type {DirectEventHandler} from '../Types/CodegenTypes';
|
||||
import type EmitterSubscription from '../vendor/emitter/EmitterSubscription';
|
||||
import RCTModalHostView from './RCTModalHostViewNativeComponent';
|
||||
import {VirtualizedListContextResetter} from '../Lists/VirtualizedListContext.js';
|
||||
|
||||
/**
|
||||
* The Modal component is a simple way to present content above an enclosing view.
|
||||
*
|
||||
@@ -159,20 +161,6 @@ class Modal extends React.Component<Props> {
|
||||
this._identifier = uniqueModalIdentifier++;
|
||||
}
|
||||
|
||||
static childContextTypes:
|
||||
| any
|
||||
| {|virtualizedList: React$PropType$Primitive<any>|} = {
|
||||
virtualizedList: PropTypes.object,
|
||||
};
|
||||
|
||||
getChildContext(): {|virtualizedList: null|} {
|
||||
// Reset the context so VirtualizedList doesn't get confused by nesting
|
||||
// in the React tree that doesn't reflect the native component hierarchy.
|
||||
return {
|
||||
virtualizedList: null,
|
||||
};
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.props.onDismiss != null) {
|
||||
this.props.onDismiss();
|
||||
@@ -236,11 +224,15 @@ class Modal extends React.Component<Props> {
|
||||
onStartShouldSetResponder={this._shouldSetResponder}
|
||||
supportedOrientations={this.props.supportedOrientations}
|
||||
onOrientationChange={this.props.onOrientationChange}>
|
||||
<ScrollView.Context.Provider value={null}>
|
||||
<View style={[styles.container, containerStyles]} collapsable={false}>
|
||||
{innerChildren}
|
||||
</View>
|
||||
</ScrollView.Context.Provider>
|
||||
<VirtualizedListContextResetter>
|
||||
<ScrollView.Context.Provider value={null}>
|
||||
<View
|
||||
style={[styles.container, containerStyles]}
|
||||
collapsable={false}>
|
||||
{innerChildren}
|
||||
</View>
|
||||
</ScrollView.Context.Provider>
|
||||
</VirtualizedListContextResetter>
|
||||
</RCTModalHostView>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user