-
Notifications
You must be signed in to change notification settings - Fork 24.8k
Closed
Labels
Ran CommandsOne of our bots successfully processed a command.One of our bots successfully processed a command.Resolution: LockedThis issue was locked by the bot.This issue was locked by the bot.
Description
When using a FlatList
and you're using the renderItem
method to create an "inline" list item, it will be rendered twice, instead of once on a data
change.
Environment
Environment:
OS: macOS High Sierra 10.13.3
Node: 4.8.2
Yarn: Not Found
npm: 4.6.1
Watchman: Not Found
Xcode: Xcode 9.2 Build version 9C40b
Android Studio: Not Found
Packages: (wanted => installed)
react: 16.2.0 => 16.2.0
react-native: 0.53.0 => 0.53.0
Expected Behavior
List items should be re-rendered only once, not twice when the data
property changes.
Actual Behavior
All items are re-rendered twice.
Steps to Reproduce
https://snack.expo.io/HkCbeluKG
Source
import React, { Component } from 'react';
import { Text, FlatList } from 'react-native';
export default class App extends Component {
constructor(props) {
super(props)
this.state = {
foo: [{ id: '1', name: 'one' }],
bar: []
}
setTimeout(() => {
this.setState({
foo: [{ id: '1', name: 'one' }, { id: '2', name: 'two' }]
})
}, 1000)
}
componentDidMount() {
console.log('mounted FlatList')
}
_keyExtractor = (item) => item.id
_renderItem = ({item}) => {
console.log(`rendering ${item.name}`) // This should fire only once when this.state.foo changes!
return (
<Text>{item.name}</Text>
)
}
render() {
return (
<FlatList
data={this.state.foo}
extraData={this.state.bar}
renderItem={this._renderItem}
keyExtractor={this._keyExtractor}
/>
)
}
}
Working source
When using a PureComponent instead, it works as expected:
class ListItem extends React.PureComponent {
constructor(props) {
super(props)
console.log(`created ListItem ${this.props.name}`)
}
componentDidUpdate() {
console.log(`updated ListItem ${this.props.name}`)
}
render() {
return (
<Text>{this.props.name}</Text>
)
}
}
class PhotoPickerScreen extends React.Component {
constructor(props) {
super(props)
this.state = {
foo: [{ id: '1', name: 'one' }],
bar: []
}
setTimeout(() => {
this.setState({
foo: [{ id: '1', name: 'one' }, { id: '2', name: 'two' }]
})
}, 1000)
}
componentDidMount() {
console.log('mounted FlatList')
}
_keyExtractor = (item) => item.id
_renderItem = ({item}) => (
<ListItem name={item.name} />
)
render() {
return (
<FlatList
data={this.state.foo}
extraData={this.state.bar}
renderItem={this._renderItem}
keyExtractor={this._keyExtractor}
/>
)
}
}
Metadata
Metadata
Assignees
Labels
Ran CommandsOne of our bots successfully processed a command.One of our bots successfully processed a command.Resolution: LockedThis issue was locked by the bot.This issue was locked by the bot.