通过API动态响应本机的make“按钮”

时间:2019-06-22 23:45:45

标签: reactjs react-native

我是React Native的新手,我一直在尝试创建一个视图,其中包含根据我从API提取的数据动态创建的按钮数量。

我的问题之一是返回的数据没有我可以指向的任何名称,例如item.number

首先,我尝试做一个<Flatlist/>,但没有得到想要的设计,像这样:

所以现在我试图用一种不同的方式来制作,但是我总是会收到错误:

  

无法读取未定义的属性“ 0”

data.json:


{  
   "sEcho":0,
   "iTotalRecords":"75",
   "iTotalDisplayRecords":"73",
   "aaData":[  
      [  
         "1",
         "1",
         "Consumidor Final",
         "999999990",
         "",
         "",
         null,
         ", ",
         "21110000",
         "1",
         "1",
         "1"
      ],
      [  
         "2",
         "1000",
         "xxxxxx",
         "xxxxx",
         "",
         "",
         null,
         ", ",
         "xxxx",
         "15",
         "1",
         "1"
      ]
   ]
}

我如何获取数据;

getClientes = async (token, opcao, search, pag, numRows) => {
  var url = "https://xxxx/xxxx/xxx/xxxx/xxx/tabelas/clientes?_token=" + token + "&opcao= " + opcao + "&search=&pag=&numRows=" + numRows;

  fetch(url)
    .then((response) => response.json())
    .then((responseJson) => {
      this.setState({
        dataSource: responseJson.aaData,
        isLoading: false,
        numRows: responseJson.iTotalDisplayRecords
      })

    console.log(responseJson.iTotalDisplayRecords + " total");
    console.log("CLIENTES: " + responseJson.aaData[0][2]);
    console.log(this.state.dataSource[0][2]);
  })
  .catch((error) => {
    console.log(error);
  })
}

我如何渲染按钮:

renderClientes = (numRows, data) => {
  console.log(numRows + "azxcvb");
  console.log(data.length + "render Clientes");
  const views = [];

  for (let i = 0; i <= numRows; i++) {
    for (let j = 0; j <= 11; j++) {
      views.push(
        <TouchableOpacity style={{ flex: 1, flexDirection: 'row', marginBottom: 3 }} key={i}>
          <View style={{ flex: 1, justifyContent: 'center', marginLeft: 5 }}>
            <Text style={{ fontSize: 18, color: 'green' }}>
              {data[i][j]}
            </Text>
          </View>
        </TouchableOpacity>
      );
    }
  }

  return views;
}

然后:

 render() {
  return (
   ...
 (this.state.numRows != 0) ? this.renderClientes(this.state.numRows, this.state.dataSource) : null)
}

我该如何解决我的问题?如果有更简单的方法可以实现,那是什么?

3 个答案:

答案 0 :(得分:1)

看起来您的numRows73,但是您的数组中只有2组行?

通常最好.map通过一个数组,这样它将自动遍历每个项目。像这样:

renderClientes = (numRows, data) => {
  console.log(numRows + "azxcvb");
  console.log(data.length + "render Clientes");

  return data.map((row, i) =>
    row.map((item, j) => (
      <TouchableOpacity style={{ flex: 1, flexDirection: 'row', marginBottom: 3 }} key={`${i},${j}`}>
          <View style={{ flex: 1, justifyContent: 'center', marginLeft: 5 }}>
              <Text style={{ fontSize: 18, color: 'green' }}>
                  {item}
              </Text>
          </View>
      </TouchableOpacity>
    ))
  );
}

答案 1 :(得分:1)

您收到此错误

  

错误:无法读取未定义的属性“ 0”,因为您要遍历n个数字数组n + 1次。

要解决此问题,只需像这样分配setState即可:

this.setState({
            dataSource: responseJson.aaData,
            isLoading: false,
            numRows: responseJson.iTotalDisplayRecords - 1
        })

正如奥斯汀·格雷科(Austin Greco)所指出的那样,请相信我,我也会去地图,当在React和JavaScript中使用数组时,一切将变得更加容易。

答案 2 :(得分:1)

首先,建议您使用API​​:

let url = "https://clientes?_token=" + token + "&opcao= ";

永远不要在URL上发送令牌,因为很容易破解它们。您可以在标头上发送隐藏的数据。


正如 @Austin Greco 所说,numRows'73',但是您的数组只有两组行。我建议将numRows作为整数而不是字符串发送。

同样,为了从数据构建复杂的接口,您应该使用可以更好地描述数据的对象,而不要像使用数组(aaData)那样。拍摄您向我们展示的图片:

您可以拥有一个像这样的对象:

{
  gt: 'GT 2019/01',
  name: 'Luis Filipe Gomes Rodrigues',
  total: '179,90 €',
  open: true,
  nif: 9999999999,
  date: '01/01/2019',
}

代替

arr = ['GT 2019/01', 'Luis Filipe Gomes Rodrigues', '179,90 €', true, 9999999999, '01/01/2019']

name = arr[1]

因此,我花了一些时间来制作小吃供您跟进:@abranhe/clients-view看起来像这样:

包装代码:

import React, { Component } from 'react';
import {
  View,
  Text,
  Image,
  StyleSheet,
  TouchableOpacity,
  Dimensions,
  ScrollView,
} from 'react-native';
import { AntDesign } from '@expo/vector-icons';

import data from './data.js';

export default class StackOverflowAnswer extends Component {
  constructor(props) {
    super(props);

    this.state = {
      data: data,
      isLoading: false,
    };
  }

  renderClientLeft(client) {
    return (
      <View style={styles.clientLeft}>
        <Text style={styles.gt}>GT {client.gt}</Text>
        <Text style={styles.name} numberOfLines={1}>
          {client.name}
        </Text>
        <Text style={styles.nifAndDate}>NIF: {client.nif}</Text>
        <Text style={styles.nifAndDate}>Data: {client.date}</Text>
      </View>
    );
  }

  renderClientRight(client) {
    let hoursColor = client.open ? '#588f40' : '#4973a3';
    let hoursText = client.open ? 'Aberto' : 'Fechado';

    return (
      <View style={styles.clientRight}>
        <View style={{ justifyContent: 'space-around' }}>
          <View style={styles.total}>
            <Text style={styles.name}>Total:</Text>
            <Text style={styles.totalVal}>{client.total}</Text>
          </View>
          <View style={[{ backgroundColor: hoursColor }, styles.hours]}>
            <Text style={styles.hoursText}>{hoursText}</Text>
          </View>
        </View>

        <View style={styles.arrowContainer}>
          <AntDesign name="right" color="#bf5e2a" />
        </View>
      </View>
    );
  }

  renderClient(client) {
    return (
      <View style={styles.clientContainer}>
        <View style={styles.client}>
          {this.renderClientLeft(client)}
          {this.renderClientRight(client)}
        </View>
      </View>
    );
  }

  renderClientes = clients => {
    return clients.map((client, i) => {
      return (
        <View key={i} style={styles.clientsSeparator}>
          {this.renderClient(client)}
        </View>
      );
    });
  };

  render() {
    const { data } = this.state;
    return (
      <ScrollView style={styles.container}>
        {this.renderClientes(data)}
      </ScrollView>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#ededed',
    marginTop: 20,
    alignItems: 'center',
  },
  clientContainer: {
    width: Dimensions.get('window').width * 0.95,
    borderWidth: 1,
    borderColor: '#000000',
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.4,
    shadowRadius: 1,
    backgroundColor: '#ffffff',
  },
  client: {
    flexDirection: 'row',
    borderRadius: 1,
    margin: 4,
  },
  clientLeft: {
    width: '60%',
    marginVertical: 5,
  },
  clientRight: {
    justifyContent: 'space-between',
    flexDirection: 'row',
    height: '100%',
    width: '40%',
  },
  gt: {
    fontWeight: '700',
    color: '#bf5e2a',
    margin: 2,
  },
  name: {
    fontWeight: '700',
    margin: 2,
  },
  nifAndDate: {
    color: '#8a8a8a',
    margin: 2,
  },
  arrowContainer: {
    justifyContent: 'center',
    alignItems: 'center',
  },
  totalVal: {
    color: '#bf5e2a',
    marginLeft: 10,
  },
  total: {
    flexDirection: 'row',
  },
  hours: {
    width: '70%',
    justifyContent: 'center',
    alignItems: 'center',
  },
  hoursText: {
    color: '#ffffff',
    margin: 5,
  },
  clientsSeparator: {
    marginBottom: 5,
  },
});