简体   繁体   中英

Getting info from two different end points into individual list items

I have data from my parent App component that is passing two different states (state.names and state.ages - both are arrays) into my card component. In my card component I want to use this data to render individual card list items (that feature each character's name and age). I haven't been able to figure out how to combine these two arrays. I've mapped both, but I'd like to match up the names with their corresponding ages.

card component -

import React, { Component } from "react";

class Card extends Component {
  render() {
    const names = this.props.data.names.map(name => {
      return (
        <div key={name.id}>
          <div>{name.first_name}</div>
          //I want the ages to go right here
          </p>
        </div>
      );
    });

    const ages = this.props.data.ages.map(age => {
      return (
        <div>
          <span>{age.number}</span>
        </div>
      );
    });

    return(
      <div className="card">
        {people}
      </div>
      )
  }
}

export default Card;

Instead of having two arrays for name and age you should have a single array of person objects with fields for name and age in your state. This can be mapped in the render method of your Card component as follows:

const people= this.props.data.persons.map(person => {
      return (
        <div key={person.id}>
          <div>{person.first_name}</div>
          <div>{person.age} </div>
          </p>
        </div>
      );
    });

You can add a second parameter to Array.map which is an index of the Array. So, assuming that the names and age are in the same order, it looks like this should work:

import React, {Component} from "react";

class Card extends Component {
  render() {
    const ages = this.props.data.ages
    const names = this.props.data.names.map((name, idx) => {
        return (
          <div key={name.id}>
            <div>{name.first_name}</div>
            <div>
              <span>{ages[idx].number}</span> 
            </div>
          </div>
        );
      });

    return (
      <div className="card">
        {people}
      </div>
    )
  }
}

export default Card;

But, it must be pointed out that it would be better to keep the arrays together within objects, rather than arbitrarily ordered in two separate arrays. (eg Should you ever sort the age array, the names and ages would no longer correspond).

I usually convert the lists into objects or Map when I get the data from the API, so, in the store it's not an array.

This way you can link one array to another using some keys. In the following example I'll use objects, because it's cleaner for presentation, but I personally prefer Map instead of pure objects, because on map you can do forEach, you can keep the original ordering. Object.keys(obj) gives you an array with keys of obj instance, ordered alphabetically.

store = {
  users: {
    'aa1001': {
      id: 'aa1001',
      first_name: 'Frank'
    },
    'aa1002': {
      id: 'aa1002',
      first_name: 'John'
    }
  },
  ages: {
    'aa1001': {
      userId: 'aa1001',
      age: 25
    },
    'aa1002': {
      userId: 'aa1002',
      age: 30
    }
  }
}

import React, { Component } from "react";

class Card extends Component {
  render() {
    const {names, ages} = this.props.data;
    const people = Object.keys(names).map(nameKey => {
      return (
        <div key={names[nameKey].id}>
          <div>{name[nameKey].first_name}</div>
          <div>ages[nameKey].age</div>
        </p>
        </div>
      );
    });

    return(
      <div className="card">
        {people}
      </div>
    )
  }
}

export default Card;

I usually do transform the response with a custom function, but a good tool that you can use is normalizr

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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