Skip to content

Commit

Permalink
Add setNativeProps
Browse files Browse the repository at this point in the history
Summary:
Curently FlatList does not implement setting native props directly like the old ListView did. This pr introduce the `setNativeProps` function which delegates to MetroListView or VirtualizedList. Thos don't have `setNativeProps` handling either, so, I delegated further to the respective ListView and Scroll components, which do have handling for it, thus, allowing to set the native props through FlatList.

Create a project with a FlatList and change a native property using `setNativeProps`:

```javascript
  componentDidMount() {
        setInterval(() => {
            this.list.setNativeProps({ style: {backgroundColor:"white"} })
        }, 1000)
    }

  render() {
    return (
      <View style={styles.container}>
        <FlatList ref={component => this.list = component}
                  style={{backgroundColor:"black"}}
                  data={[{key: 'a'}, {key: 'b'}]}
                  renderItem={({item}) => <Text>{item.key}</Text>} />
      </View>
    )
  }
```

Fixes #13501
Closes #13529

Differential Revision: D5283593

Pulled By: sahrens

fbshipit-source-id: 8f96f88e286042d82452fef924689b5a8a783987
  • Loading branch information
reneweb authored and facebook-github-bot committed Jun 20, 2017
1 parent 60783aa commit 75508c1
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 0 deletions.
6 changes: 6 additions & 0 deletions Libraries/Lists/FlatList.js
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,12 @@ class FlatList<ItemT>
}
}

setNativeProps(props: Object) {
if (this._listRef) {
this._listRef.setNativeProps(props);
}
}

componentWillMount() {
this._checkProps(this.props);
}
Expand Down
5 changes: 5 additions & 0 deletions Libraries/Lists/MetroListView.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ class MetroListView extends React.Component {
getListRef() {
return this._listRef;
}
setNativeProps(props: Object) {
if (this._listRef) {
this._listRef.setNativeProps(props);
}
}
static defaultProps: DefaultProps = {
keyExtractor: (item, index) => item.key || String(index),
renderScrollComponent: (props: Props) => {
Expand Down
6 changes: 6 additions & 0 deletions Libraries/Lists/VirtualizedList.js
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,12 @@ class VirtualizedList extends React.PureComponent<OptionalProps, Props, State> {
}
}

setNativeProps(props: Object) {
if (this._scrollRef) {
this._scrollRef.setNativeProps(props);
}
}

static defaultProps = {
disableVirtualization: false,
horizontal: false,
Expand Down

1 comment on commit 75508c1

@technoplato
Copy link

@technoplato technoplato commented on 75508c1 Sep 25, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @sahrens @reneweb I've been looking at trying to imperatively set the onEndReached prop of my FlatList imperatively. Is there a way to do that? I've modified your example to toggle the color from black to white on an interval, but can't get onEndReached to be called. Can you help me understand what I'm doing wrong?

export default class Testing extends React.Component {
  componentDidMount() {
    let tick = 0
    this.list.setNativeProps({
      onEndReached: info => {
        // NEVER CALLED 😢
        console.log('L231 on Scroll info ===', info)
      },

      onScroll: info => {
        // NEVER CALLED 😢
        console.log('L250 info ===', info)
      },

      // Background DOES flash red on load... 🤔 
      style: { backgroundColor: 'red' }
    })
    setInterval(() => {
      this.list.setNativeProps({
        onEndReached: info => {
          console.log('L231 on Scroll info ===', info)
        },

        // Background DOES toggle black and white... 🤔 
        style: { backgroundColor: tick++ & 2 ? 'white' : 'black' }
      })
    }, 1000)
  }

  render() {
    return (
      <View style={styles.container}>
        <FlatList
          ref={component => (this.list = component)}
          style={{ backgroundColor: 'black' }}
          data={[{ key: 'a' }, { key: 'b' }]}
          renderItem={({ item }) => <Text>{item.key}</Text>}
        />
      </View>
    )
  }
}

Please sign in to comment.