Извлекать и группировать данные JSON для FlatList в React-Native - PullRequest
0 голосов
/ 27 декабря 2018

Вот мой оригинальный Json .Я использую fetch и Flatlist для получения и отображения данных JSON.Мои коды работают правильно, но я хочу отделить JSON по «полу», как показано ниже.Я исследовал групповую работу и сократил функции, но не смог найти решение.

"gender": "male" {
    {name,location...},
    {name,location...},
    {name,location...}
},
"gender": "female" {
    {name,location...},
    {name,location...},
    {name,location...}
}

Коды RN;

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

  componentDidMount(){
    return fetch('https://randomuser.me/api/?results=5')
      .then((response) => response.json())
      .then((responseJson) => {

        this.setState({
          isLoading: false,
          dataSource: responseJson.results,
        }, function(){
        });

      })
      .catch((error) =>{
        console.error(error);
      });
  }

  render() {

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

    return(
      <View style={{flex: 1, paddingTop:20}}>
        <FlatList
          data={this.state.dataSource}
          renderItem={({item}) => 
            <View><Text>{item.name.first},{item.gender}</Text></View>
          }
          keyExtractor={({id}, index) => id}
        />
      </View>
    );
  }
}

1 Ответ

0 голосов
/ 27 декабря 2018

Если я правильно понимаю ваш вопрос, вы хотите сгруппировать данные по полу и представить группировки в виде компонента, подобного списку.В этом случае <SectionList> компонент может быть более подходящим для этого, поскольку вы вводите дополнительную структуру в dataSource.

Чтобы использовать <SectionList>,сначала измените вашу render() функцию следующим образом:

return (<View style={{flex: 1, paddingTop:20}}>
    <SectionList
      data={ this.state.dataSource }
      renderSectionHeader={ 
          ({ section : { gender }}) => (<Text>{ gender }</Text>) 
      }
      renderItem={ 
          ({item}) => (<Text>{item.name.first},{item.gender}</Text>) 
      }
      keyExtractor={(item, index) => item.login.uuid + index}
    />
  </View>);

<SectionList> требует, чтобы dataSource был организован с вложенным массивом data для каждого раздела, поэтому вам потребуется выполнить следующие дополнительныеРаботайте над преобразованием responseJson.results в подходящий формат перед обновлением dataSource в состоянии вашего компонента:

componentDidMount(){
return fetch('https://randomuser.me/api/?results=5')
  .then((response) => response.json())
  .then((responseJson) => {

    // Add this to process responseJson.results and pass dataSource result to setState()
    const dataSource = responseJson.results.reduce(function(sections, item) {

       let section = sections.find(section => section.gender === item.gender);

       if(!section) {
          section = { gender : item.gender, data : [] };
          sections.push(section);
       }

       section.data.push(item);

       return sections;

    }, []);

    this.setState({
      isLoading: false,
      dataSource: dataSource // Pass the dataSource that we've processed above
    });

  })
  .catch((error) =>{
    console.error(error);
  });

Наконец, вы захотите обновить свое начальное состояние в конструкторе компонентов, чтобы убедиться, что render()можно выполнить, когда запрос fetch() занят, добавив:

constructor(props){
    super(props);
    this.state ={ 
        isLoading: true,
        dataSource: [] // Add this
    }
}

Вот фрагмент рабочего кода, показывающий, как обрабатываются данные JSON для группировки их по ключу пола - надеюсь, это поможет!

var responseJson = {
"results": [
{
"gender": "female",
"name": {},
"location": {},
"email": "karla.ferreira@example.com",
"login": {
"uuid": "86f5b29b-1f36-4082-8b88-18df6c5985f9",
"username": "orangebutterfly557",
"password": "kojak",
"salt": "7mybIlaS",
"md5": "c85980c5ce76b38b71d162402d71eb1c",
"sha1": "e38b87aaf2d5be040ed0741faea0e4b97d52fd35",
"sha256": "9f44b3da697a63b4d5c393513ab651e8fe0315d1ee199d5bd03797279189c881"
},
"dob": {
"date": "1990-07-01T17:43:24Z",
"age": 28
},
"registered": {
"date": "2018-05-17T15:57:05Z",
"age": 0
},
"phone": "(73) 6539-5154",
"cell": "(52) 4127-1768",
"id": {
"name": "",
"value": null
},
"picture": {
"large": "https://randomuser.me/api/portraits/women/41.jpg",
"medium": "https://randomuser.me/api/portraits/med/women/41.jpg",
"thumbnail": "https://randomuser.me/api/portraits/thumb/women/41.jpg"
},
"nat": "BR"
},
{
"gender": "female",
"name": {
"title": "ms",
"first": "isabel",
"last": "caballero"
},
"location": {
"street": "7168 calle de bravo murillo",
"city": "valladolid",
"state": "canarias",
"postcode": 79290,
"coordinates": {
"latitude": "-69.7045",
"longitude": "4.0689"
},
"timezone": {
"offset": "-9:00",
"description": "Alaska"
}
},
"email": "isabel.caballero@example.com",
"login": {
"uuid": "794613c2-cac6-4c71-a2b6-f2ce119b46d2",
"username": "beautifulbutterfly648",
"password": "beer",
"salt": "5fhMSsyZ",
"md5": "ee62bb75d8f0a95d1d0788fff592e6dc",
"sha1": "71aa4f04cba4a601a52e358b1986a627edecab5a",
"sha256": "b5c3c0b607f15454f0faa8d7f68fc0fa981b9b3283fc9f37cf0ecf2a0f608c8d"
},
"dob": {
"date": "1951-03-16T06:28:07Z",
"age": 67
},
"registered": {
"date": "2008-08-12T17:02:44Z",
"age": 10
},
"phone": "938-596-606",
"cell": "604-802-919",
"id": {
"name": "DNI",
"value": "08944217-Q"
},
"picture": {
"large": "https://randomuser.me/api/portraits/women/18.jpg",
"medium": "https://randomuser.me/api/portraits/med/women/18.jpg",
"thumbnail": "https://randomuser.me/api/portraits/thumb/women/18.jpg"
},
"nat": "ES"
},
{
"gender": "male",
"name": {
"title": "mr",
"first": "owen",
"last": "ouellet"
},
"location": {
"street": "8868 frederick ave",
"city": "waterloo",
"state": "newfoundland and labrador",
"postcode": "J9T 1I9",
"coordinates": {
"latitude": "-74.7042",
"longitude": "-147.1181"
},
"timezone": {
"offset": "-3:30",
"description": "Newfoundland"
}
},
"email": "owen.ouellet@example.com",
"login": {
"uuid": "91634e9f-9a0b-406d-83f1-f0df7731c922",
"username": "beautifulleopard930",
"password": "valkyrie",
"salt": "OEfVANKW",
"md5": "bda8ccb4284727538bd24994ee1a91ef",
"sha1": "f193f9836421fa287f01e8f8305140b0d2d87596",
"sha256": "28a0197375cdfc8d22ec0e388ef93f18705dcb909d6944719f217d60ac45cd24"
},
"dob": {
"date": "1978-04-05T03:58:10Z",
"age": 40
},
"registered": {
"date": "2008-09-04T08:08:37Z",
"age": 10
},
"phone": "527-612-8558",
"cell": "573-419-2272",
"id": {
"name": "",
"value": null
},
"picture": {
"large": "https://randomuser.me/api/portraits/men/60.jpg",
"medium": "https://randomuser.me/api/portraits/med/men/60.jpg",
"thumbnail": "https://randomuser.me/api/portraits/thumb/men/60.jpg"
},
"nat": "CA"
},
{
"gender": "female",
"name": {
"title": "mrs",
"first": "lily",
"last": "campbell"
},
"location": {
"street": "6239 dalhousie ave",
"city": "brockton",
"state": "northwest territories",
"postcode": "X6R 5W4",
"coordinates": {
"latitude": "44.3179",
"longitude": "77.2683"
},
"timezone": {
"offset": "+3:30",
"description": "Tehran"
}
},
"email": "lily.campbell@example.com",
"login": {
"uuid": "5e7f5ca7-1c6a-49cf-98ea-6993ba13e98d",
"username": "sadleopard720",
"password": "noodles",
"salt": "dO6LaBuZ",
"md5": "3b946373260729b1c598fc76b953b0f7",
"sha1": "9df4c90b67eb00fb5f46b291d006333418b837cb",
"sha256": "05bc6bc7749a7483e45afcd2cf13a44642253d69ad2164e7315d04ae12a54178"
},
"dob": {
"date": "1995-10-01T19:06:38Z",
"age": 23
},
"registered": {
"date": "2013-10-20T00:40:17Z",
"age": 5
},
"phone": "474-554-3856",
"cell": "280-264-4427",
"id": {
"name": "",
"value": null
},
"picture": {
"large": "https://randomuser.me/api/portraits/women/9.jpg",
"medium": "https://randomuser.me/api/portraits/med/women/9.jpg",
"thumbnail": "https://randomuser.me/api/portraits/thumb/women/9.jpg"
},
"nat": "CA"
},
{
"gender": "male",
"name": {
"title": "mr",
"first": "matias",
"last": "salo"
},
"location": {
"street": "1152 itsenäisyydenkatu",
"city": "lieksa",
"state": "northern ostrobothnia",
"postcode": 89650,
"coordinates": {
"latitude": "15.4636",
"longitude": "84.5787"
},
"timezone": {
"offset": "+11:00",
"description": "Magadan, Solomon Islands, New Caledonia"
}
},
"email": "matias.salo@example.com",
"login": {
"uuid": "562f43c4-5fc1-45f2-bb27-99516a0ae907",
"username": "sadcat151",
"password": "aaaaaaaa",
"salt": "CpmHRSKk",
"md5": "ea3078f64987b8c1d6e697d871a3239e",
"sha1": "bdd64c7d8bb3383a3ac24b6716214385972127be",
"sha256": "5ccfa3847e4c0a7878dd35ccbcabcc7b411f8b95f15d222100edc8cd79cabbd4"
},
"dob": {
"date": "1964-02-17T18:40:47Z",
"age": 54
},
"registered": {
"date": "2004-12-03T13:58:39Z",
"age": 14
},
"phone": "08-963-701",
"cell": "047-041-00-91",
"id": {
"name": "HETU",
"value": "NaNNA305undefined"
},
"picture": {
"large": "https://randomuser.me/api/portraits/men/60.jpg",
"medium": "https://randomuser.me/api/portraits/med/men/60.jpg",
"thumbnail": "https://randomuser.me/api/portraits/thumb/men/60.jpg"
},
"nat": "FI"
}
],
"info": {
"seed": "21ef5612af5cb358",
"results": 5,
"page": 1,
"version": "1.2"
}
};

const result = responseJson.results.reduce(function(sections, item) {
    
  let section = sections.find(section => section.gender === item.gender);
  
  if(!section) {
    section = { gender : item.gender, data : [] };
    sections.push(section);
  }
  
  section.data.push(item);
  
  return sections;
  
}, []);

console.log(result);
.as-console-wrapper {
height:100% !important;
max-height:unset !important;
}
...