简体   繁体   English

在遍历数组对象以创建列表项时遇到麻烦

[英]Having trouble looping through array object to create list items

I'm able to loop through JSON data to create an array filled with numbers, but when I go to create the list items it doesn't work. 我能够遍历JSON数据来创建一个填充数字的数组,但是当我创建列表项时,它不起作用。 The component just renders an empty list. 该组件仅呈现一个空列表。

When I console.log(ticketNumbers) right before the map function, it shows as a collapsed Array [] until I expand it (it then shows all the values) 当我在map函数之前console.log(ticketNumbers)时,它显示为折叠的Array [],直到我展开它为止(然后显示所有值)

function apiCall() {
  var ticketNumbers = [];
  var memId = 'xxx'; 
  var myInit = { 
      method: 'GET',
      mode: 'cors',
      headers: {
        'authorization': "xxx",
    'Access-Control-Allow-Origin':'*',
    'content-type': "application/json",
    'cache-control': "no-cache"
          },
      params: {
    'orderBy': 'status/name asc',
    'pageSize': 300,
    'conditions': "resources contains '" + memId + "' AND status/id not in (17,165,36,163,164,42,73,46,78,148,34,132,45,159,60,168,106,51,72,95)"
          }
  };
  axios.get('Url', myInit)
    .then((response) => {
      console.log(response.data)
      for (var ticket in response.data) {
        ticketNumbers.push(response.data[ticket].id)
      };  
     })
    return ticketNumbers
}
class TicketContainer extends Component {
  constructor(props) {
    super(props)
    this.state = {
      data: [],
      loading: true,
    };
  }
  componentWillMount() {
      this.setState({
        data: {
      numbers: apiCall()
        },      
      loading: false
        })
      };
  render() {
    return(
      <div>
    {this.state.loading ? 'Loading' : <Tickets data={this.state.data} />}
      </div>
    )
  }
}

class Tickets extends Component {
  render() {
    const stuff = this.props;
    var ticketList = stuff.data.numbers;
    console.log(ticketList);
    return(
      <div>
        <ul>Ticket Number
          {ticketList.map((ticket, index) => {
            return <li key={index}>sweet</li>;
          })}   
        </ul>
      </div>
    );
  }
}

You should correctly use Promise to solve this. 您应该正确使用Promise解决此问题。 First, let's change apiCall so that it will return a Promise: 首先,让我们更改apiCall,使其返回Promise:

function apiCall() {
  var ticketNumbers = [];
  var memId = 'xxx'; 
  var myInit = { 
      method: 'GET',
      mode: 'cors',
      headers: {
        'authorization': "xxx",
    'Access-Control-Allow-Origin':'*',
    'content-type': "application/json",
    'cache-control': "no-cache"
          },
      params: {
    'orderBy': 'status/name asc',
    'pageSize': 300,
    'conditions': "resources contains '" + memId + "' AND status/id not in (17,165,36,163,164,42,73,46,78,148,34,132,45,159,60,168,106,51,72,95)"
          }
  };
  return axios.get('Url', myInit)
    .then((response) => {
      console.log(response.data)
      for (var ticket in response.data) {
        ticketNumbers.push(response.data[ticket].id)
      }
      return ticketNumbers;
     });
}

You know have a Promise based api that can be used like this: 您知道有一个基于Promise的api,可以这样使用:

apiCall().then(ticketNumbers => console.log(ticketNumbers);

We just need to modify componentWillMount know: 我们只需要修改componentWillMount就知道:

componentWillMount() {
     apiCall().then(numbers => this.setState({ loading: false, data: numbers });
}

The apiCall function calls an API which is asynchronous process and returning ticketNumbers from function request won't return the result as the return statement will be executed before the API response is ready and ticketNumbers array is populated. apiCall函数调用一个异步过程的API,并且从函数请求返回ticketNumbers 不会返回结果,因为return语句将在API响应准备好并填充ticketNumbers数组之前执行。

The easiest way for you to do this is to define this function in the React class and directly setState in the callback of axios request 最简单的方法是在React类中定义此函数,然后在axios请求的回调中直接设置setState

class TicketContainer extends Component {
  constructor(props) {
    super(props)
    this.state = {
      data: [],
      loading: true,
    };
  }
  componentWillMount() {
      this.apiCall()

  };


  apiCall =() => {

      var memId = 'xxx'; 
      var myInit = { 
          method: 'GET',
          mode: 'cors',
          headers: {
            'authorization': "xxx",
            'Access-Control-Allow-Origin':'*',
            'content-type': "application/json",
            'cache-control': "no-cache"
          },
          params: {
            'orderBy': 'status/name asc',
            'pageSize': 300,
            'conditions': "resources contains '" + memId + "' AND status/id not in (17,165,36,163,164,42,73,46,78,148,34,132,45,159,60,168,106,51,72,95)"
              }
      };
      axios.get('Url', myInit)
        .then((response) => {
          var ticketNumbers = [];
          for (var ticket in response.data) {
            ticketNumbers.push(response.data[ticket].id)
          }; 
          this.setState({data: ticketNumbers, loading: false}) 
         })
  }
  render() {
    return(
      <div>
    {this.state.loading ? 'Loading' : <Tickets data={this.state.data} />}
      </div>
    )
  }
}

class Tickets extends Component {
  render() {
    const stuff = this.props;
    var ticketList = stuff.data.numbers;
    console.log(ticketList);
    return(
      <div>
        <ul>Ticket Number
          {ticketList.map((ticket, index) => {
            return <li key={index}>sweet</li>;
          })}   
        </ul>
      </div>
    );
  }
}

In case you are wondering why the console.log() statment logs the array, check this answer Value below was evaluated just now in JavaScript object 如果您想知道console.log()语句为何记录该数组,请检查此答案刚刚在JavaScript对象中评估了下面的值

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM