Flatlist in Modal unable to scroll
See original GitHub issue- [ x] I have reviewed the documentation
- [ x] I have searched existing issues
- [ x] I am using the latest React Native version
I’m having an issue with scrolling in lists that are in modals ever since upgrading from 0.46.4 to the latest React-Native version (0.55.4). In this case it is a Flatlist.
The Flatlist with the problem is inside a modal, which is in another modal that is rendered as a footer component on another Flatlist (it is an add button).
Initial page: Flatlist items, footer component: add button Add Button: Modal with input fields. Upon clicking an input field another modal pops up. Input field: Modal with Flatlist
Environment
Environment: OS: Linux 4.13 Node: 8.9.1 Yarn: 1.5.1 npm: 4.6.1 Watchman: Not Found Xcode: N/A Android Studio: Not Found
Packages: (wanted => installed) react: ^16.3.2 => 16.3.2 react-native: ^0.55.4 => 0.55.4
Steps to Reproduce
Add button code (button component is my own):
import { observable } from 'mobx';
import { observer } from 'mobx-react';
@observer
class AddButton extends Component {
@observable visible = false;
constructor(props) {
super(props);
this.state = {
mergeName: '',
coin: undefined
};
}
show = () => {
this.visible = true;
};
hide = () => {
this.visible = false;
};
render() {
return (
<View>
<Button
primary
onPress={() => {
this.show();
}}
title={'add'}
style={{
width: '50%',
alignSelf: 'center',
marginVertical: 16
}}
/>
<Modal
visible={this.visible}
animationType='slide'
onRequestClose={this.hide}
>
<Screen>
<View style={{ padding: 5, backgroundColor: '#0003' }}>
<TouchableOpacity
style={{
width: '50%',
height: 40,
paddingHorizontal: 10,
justifyContent: 'center'
}}
onPress={this.hide}
>
<Text style={{ color: '#fff' }}>
{'cancel'}
</Text>
</TouchableOpacity>
</View>
<View>
<Row>
<RowLabel>{'coin'}:</RowLabel>
<Selector
force
ref={'mySelector'}
value={this.coin}
onSelect={coin => {
this.handleSelect();
}}
data={allCoins}
/>
</Row>
<Button
primary
onPress={this.handleSubmit}
title={this.props.i18n.'add'}
style={{
width: '50%',
alignSelf: 'center',
marginVertical: 16
}}
/>
</View>
</Screen>
</Modal>
</View>
);
}
}
export default AddButton;
const contentStyle = {
flex: 1,
backgroundColor: '#0003',
paddingLeft: 10,
borderRadius: 3
};
const Row = ({ style, ...rest }) => (
<View
style={[
{
height: 60,
flexDirection: 'row',
alignItems: 'center',
padding: 10,
marginRight: 10
},
style
]}
{...rest}
/>
);
const RowLabel = props => (
<Text style={{ width: 80, color: '#ccc' }} {...props} />
);
const Input = (props: TextInputProperties) => (
<View style={contentStyle}>
<TextInput
placeholderTextColor='#fff3'
style={{ color: '#ccc', flex: 1, fontSize: 14 }}
{...props}
/>
</View>
);
Problematic Flatlist code:
@observer
class Selector extends Component {
@observable value = '';
@observable visible = false;
constructor(props) {
super(props);
if (props.modify) {
this.selectValue();
}
}
selectValue = () => {
this.value = this.props.value;
};
show = () => {
if (this.props.force) this.visible = true;
if (!this.props.coin) return;
this.visible = true;
};
hide = () => {
this.filterText = '';
this.visible = false;
};
handleSelect = item => {
this.value = item;
if (typeof this.props.onSelect === 'function') {
this.props.onSelect(item);
}
this.hide();
};
componentWillReceiveProps(nextProps) {
if (nextProps.value !== this.value) {
this.value = nextProps.value || '';
}
}
renderItem = ({ item }) => {
return (
<TouchableOpacity
onPress={() => this.handleSelect(item)}
style={{
backgroundColor: '#fff',
height: 40,
paddingLeft: 10,
justifyContent: 'center'
}}
>
<Text style={{ fontSize: 14, color: '#333' }}>
{item.toUpperCase()}
</Text>
</TouchableOpacity>
);
};
render() {
let data = this.props.data;
return (
<View style={[ contentStyle, { justifyContent: 'center' } ]}>
<TouchableOpacity
style={{
flex: 1,
flexDirection: 'row',
alignItems: 'center'
}}
onPress={this.show}
>
<Text
numberOfLines={1}
style={{ color: this.value ? '#ccc' : '#fff3' }}
>
{(
this.value ||
this.props.placeholder ||
''
).toUpperCase()}
</Text>
</TouchableOpacity>
<Modal
transparent
animationType='fade'
visible={this.visible}
onRequestClose={this.hide}
>
<View
style={{
flex: 1,
backgroundColor: '#0005',
alignItems: 'center',
paddingTop: 80
}}
>
<View
style={{
width: '80%',
backgroundColor: '#fff',
borderRadius: 5,
maxHeight: '80%',
overflow: 'hidden'
}}
>
<FlatList
data={data}
keyExtractor={i => i}
getItemLayout={(_, index) => {
const height = 40 + HairSpacer.width;
return {
length: height,
offset: height * index,
index
};
}}
ItemSeparatorComponent={HairSpacer}
renderItem={this.renderItem}
/>
</View>
<TouchableOpacity
onPress={this.hide}
style={{ marginTop: 12 }}
>
<Icon
name='ios-close-circle'
size={50}
color='#ccc'
/>
</TouchableOpacity>
</View>
</Modal>
</View>
);
}
}
export default Selector;
const contentStyle = {
flex: 1,
backgroundColor: '#0003',
paddingLeft: 10,
borderRadius: 3
};
Expected Behavior
I expect to be able to scroll freely, as in previous versions of react-native
Actual Behavior
Cannot scroll the flatlist. Tried all the suggested options online, including flexgrow, messing around with other styling, onStartShouldSetResponder, etc
Issue Analytics
- State:
- Created 5 years ago
- Reactions:2
- Comments:12
Top Related StackOverflow Question
Having this same issue, @abeddow91 solution worked for me:
Dont’ forget to move any container styles from the
FlatListto theScrollViewI managed to get around this by wrapping the flatlist within a scrollview - not very nice code but its working as expected