Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React-Native Rendering json flatlist

I am new to react-native. I'm building up complexity but have gotten stuck on rendering FlatList items from a json list. This was working fine for ListView but not able to figure out what I am missing on FlatList.

import React, { Component } from 'react';
import { ActivityIndicator, ListView, Text, View, StyleSheet,TouchableOpacity, FlatList  } from 'react-native';

export default class Movies extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isLoading: true
    }
  }

  componentDidMount() {
    return fetch('https://gnosisdevelopment.com/office/list.json')
      .then((response) => response.json())
      .then((responseJson) => {
        let data_source = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
        this.setState({
          isLoading: false,
          dataSource: data_source.cloneWithRows(responseJson.office_staff),
        }, function() {
          // do something with new state
        });
      })
      .catch((error) => {
        console.error(error);
      });
  }

  render() {
    if (this.state.isLoading) {
      return (
        <View style={{flex: 1, paddingTop: 20}}>
          <ActivityIndicator />
        </View>
      );
    }

    return (
      <View style={styles.container}>
        <FlatList
          data={this.state.dataSource}
          renderItem={({item}) =>
                    <Text style={styles.touchButtonText}>{item.staff_name} </Text>
          }
        />
      </View>
    );
  }
}
const styles = StyleSheet.create({
container: {
    flex:1,
    alignItems: 'center',
    alignContent:'center',
    flexDirection: 'row',
    flexWrap:'wrap',
    justifyContent:'center',
},
touchButton:{
    alignSelf:'center',
    backgroundColor:'#2980b9',
    paddingVertical: 25,
    width:295,
    margin:15,
},
touchButtonText:{
  textAlign:'center',
  color:'#ffffff',
  fontWeight:'bold'
},

})

The text field will be in a touchable and I'll be adding function to the buttons but I wanted to get the listing correct first. Any suggestions are welcome. Thanks for the help :)

https://gnosisdevelopment.com/office/list.json

 {
  "title": "Welcome to our office",
  "description": "Your smart office assistant",
  "office_staff": [
    { "staff_name": "Dr. Bob"},
    { "staff_name": "Dr. Xavior"},
    { "staff_name": "Dr. Sanchez"},
    { "staff_name": "Dr. Robert"},
    { "staff_name": "Dr. Albert"}
  ]
}

UPDATE with new datasource load:

    import React, { Component } from 'react';
    import { ActivityIndicator, ListView, Text, View, StyleSheet,TouchableOpacity, FlatList  } from 'react-native';

    export default class Office extends Component {
      constructor(props) {
        super(props);
        this.state = {
          isLoading: true,
          dataSource: [],
        } 
      }

      componentDidMount() {
          return fetch('https://gnosisdevelopment.com/office/list.json')
            .then((response) => response.json())
            .then((responseJson) => {
             // just setState here e.g.
             this.setState({ dataSource: responseJson.office_staff, isLoading:false,});
            })
            .catch((error) => {
              console.error(error);
            });
        }
      render() {
        if (this.state.isLoading) {
          return (
            <View style={{flex: 1, paddingTop: 20}}>
              <ActivityIndicator />
            </View>
          );
        }

       return (
      <View style={styles.container}>
        <FlatList
          data={this.state.dataSource}
          renderItem={({item}) =><Text style={styles.touchButtonText}>{item.staff_name}</Text>
          }
          keyExtractor={(item, index) => index}
        />
      </View>
    );
  }
}
    const styles = StyleSheet.create({
    container: {
        flex:1,
        alignItems: 'center',
        alignContent:'center',
        flexDirection: 'row',
        flexWrap:'wrap',
        justifyContent:'center',
    },
    touchButton:{
        alignSelf:'center',
        backgroundColor:'#2980b9',
      paddingVertical: 25,
        width:295,
        margin:15,
    },
    touchButtonText:{
      textAlign:'center',
      color:'#ffffff',
      fontWeight:'bold'
    },

    })

Final working version:

import React, { Component } from 'react';
import { ActivityIndicator, Text, View, StyleSheet,TouchableOpacity, FlatList  } from 'react-native';

export default class Office extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isLoading: true,
      dataSource: [],
    }
  }

  componentDidMount() {
      return fetch('https://gnosisdevelopment.com/office/list.json')
        .then((response) => response.json())
        .then((responseJson) => {
         // just setState here e.g.
         this.setState({ dataSource: responseJson.office_staff,isLoading: false });
        })
        .catch((error) => {
          console.error(error);
        });
    }
  render() {
    if (this.state.isLoading) {
      return (
        <View style={{flex: 1, paddingTop: 20}}>
          <ActivityIndicator />
        </View>
      );
    }

    return (
      <View style={styles.container}>
        <FlatList
          data={this.state.dataSource}
          renderItem={({item}) =><Text>{item.staff_name}</Text>}
          keyExtractor={(item, index) => index}
        />
      </View>
    );
  }
}
const styles = StyleSheet.create({
container: {
    flex:1,
    alignItems: 'center',
    alignContent:'center',
    flexDirection: 'row',
    flexWrap:'wrap',
    justifyContent:'center',
},
touchButton:{
    alignSelf:'center',
    backgroundColor:'#2980b9',
  paddingVertical: 25,
    width:295,
    margin:15,
},
touchButtonText:{
  textAlign:'center',
  color:'#ffffff',
  fontWeight:'bold'
},

})
like image 273
James Avatar asked Oct 29 '22 22:10

James


1 Answers

You don't need to provide a dataSource like that.

  constructor(props) {
    super(props);
    this.state = {
      isLoading: true,
      dataSource: [], 
    }
  }
componentDidMount() {
    return fetch('https://gnosisdevelopment.com/office/list.json')
      .then((response) => response.json())
      .then((responseJson) => {
       // just setState here e.g. 
       this.setState({ 
           dataSource: responseJson.office_staff,
           isLoading: false,  
       });         
      })
      .catch((error) => {
        console.error(error);
      });
  }
like image 91
Tim Avatar answered Nov 08 '22 04:11

Tim