Search code examples
reactjsreact-nativereact-hookspull-to-refreshuirefreshcontrol

Can you use React Native RefreshControl without hooks?


I want to use RefreshControl in my React Native app, but the demo implementation in their docs uses hooks, which I'm not using in my app. When I copy paste the demo code, I get the error Hooks can only be called inside of the body of a function component. Is there a way for me to use this library without converting my component to a function component?


Solution

  • You can use the RefreshControl in a class-based component and therefore avoid hooks. Here is an example:

    import React, { Component } from 'react';
    import { StyleSheet, View, ListView, RefreshControl, Text } from 'react-native'
    
    
    class RefreshControlExample extends Component {
      constructor () {
        super()
        this.state = {
          refreshing: false,
          dataSource: new ListView.DataSource({
            rowHasChanged: (row1, row2) => row1 !== row2 }),
          cars : [
            {name:'BMW',color:'White'},
            {name:'Mercedes',color:'Green'}
          ]
        }
      }
    
       componentWillMount(){
         this.setState({ dataSource:
           this.state.dataSource.cloneWithRows(this.state.cars) })
       }
    
      render() {
        return (
          <View style={{flex:1}}>
            <ListView
              refreshControl={this._refreshControl()}
              dataSource={this.state.dataSource}
              renderRow={(car) => this._renderListView(car)}>
            </ListView>
          </View>
        )
      }
    
      _renderListView(car){
        return(
          <View style={styles.listView}>
            <Text>{car.name}</Text>
            <Text>{car.color}</Text>
          </View>
        )
      }
    
      _refreshControl(){
        return (
          <RefreshControl
            refreshing={this.state.refreshing}
            onRefresh={()=>this._refreshListView()} />
        )
      }
    
      _refreshListView(){
        //Start Rendering Spinner
        this.setState({refreshing:true})
        this.state.cars.push(
          {name:'Fusion',color:'Black'},
          {name:'Yaris',color:'Blue'}
        )
        //Updating the dataSource with new data
        this.setState({ dataSource:
            this.state.dataSource.cloneWithRows(this.state.cars) })
        this.setState({refreshing:false}) //Stop Rendering Spinner
      }
    
    }
    
    const styles = StyleSheet.create({
    
      listView: {
        flex: 1,
        backgroundColor:'#fff',
        marginTop:10,
        marginRight:10,
        marginLeft:10,
        padding:10,
        borderWidth:.5,
        borderColor:'#dddddd',
        height:70
      }
    
    })
    
    export default RefreshControlExample;