Reactjs ПОЛУЧАЕТ МЕТОД извлечения данных из api в таблице

#json #reactjs #react-hooks

Вопрос:

это то, что у меня есть в файле компонента

 <div>
      <Table striped>
        <thead>
        <tr>
          <th>#Number</th>
          <th>item</th>
          <th>description</th>
          <th>quantity</th>
          <th>price</th>
        </tr>
        </thead>
        <tbody>
        {items amp;amp; items.map(item => {
          return (
            <tr>
              <th scope="row">{item.id}</th>
              <td>{item.items.map(item => <tr>{item.description}</tr>)}</td>
              <td>{item.items.map(item => <tr>{item.item}</tr>)}</td>
              <td>{item.items.map(item => <tr>{item.quantity}</tr>)}</td>
              <td>{item.items.map(item => <tr>{item.price}</tr>)}</td>
            </tr>
          );
        })}
        </tbody>
      </Table>
    </div>
 

а это мой json из api

 [
{
    "id": 1,
    "invoiceno": "invoice1",
    "description": "invoice1",
    "taxrate": 10,
    "issuedate": "2021-07-14T23:00:00.000Z",
    "duedate": "2021-07-15T23:00:00.000Z",
    "note": "invoice1",
    "taxamount": 10,
    "subtotal": 100,
    "total": 100,
    "updatedAt": "2021-05-26T23:00:00.000Z",
    "updatedBy": 14,
    "createdAt": "2021-06-01T23:00:00.000Z",
    "createdBy": 25,
    "items": [
        {
            "id": 1,
            "description": "item1",
            "item": 25,
            "quantity": 23,
            "price": 23,
            "idInvoice": 1
        },
        {
            "id": 2,
            "description": "item2",
            "item": 23,
            "quantity": 15,
            "price": 12,
            "idInvoice": 1
        }
    ]
}
 ]
 

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

это функция метода GET, которую я использую, чтобы вы могли ее хорошо видеть

      const [items, setItems] = useState([])

     const getItems= () => {
     fetch(`${process.env.REACT_APP_API_URL}/invoice/${urlElements[4]}`, 
       {
      method: 'GET',
      headers: {
    'Content-Type': 'application/json',
    'x-business-name' : 'billings',
    "Accept":"application/json"
  },

})
  .then(response => response.json())
  .then(items => setItems(items))
  .catch(err => console.log(err))
   }

   useEffect(() => {
      getItems()
     }, []);
 

Ответ №1:

Вы не должны вкладывать a tr непосредственно в a td , но все же — он делает то, что говорит ваш код. У вас есть первая строка , в которой сначала печатается идентификатор основного объекта (#1) th , а затем вы открываете a td и повторяете каждый дочерний item элемент в a tr , что в вашем случае означает, что у каждого td есть две записи (дочерний элемент 1 и дочерний элемент 2).

Обновление — ваше состояние items представляет собой массив, и затем вы тоже хотите вложить items его в каждый из них. Вот пример, основанный на той части вашего кода, которую я вижу, и некоторых вещах, которые мне пришлось придумать, потому что я не могу видеть все это.

 export default function MyComponent() {
  // Renaming so it's more clear and doesn't conflict with the
  // child `items`
  const [itemsFromApi, setItemsFromApi] = useState([])
  
  // Renaming
  const getItemsFromApi = () => {
  fetch(`${process.env.REACT_APP_API_URL}/invoice/${urlElements[4]}`, {
  method: 'GET',
  headers: {
    'Content-Type': 'application/json',
    'x-business-name' : 'billings',
    "Accept":"application/json"
  },
    })
    .then(response => response.json())
    .then(data => setItemsFromApi(data))
    .catch(err => console.log(err))
  }

  useEffect(() => {
    getItemsFromApi()
  }, []);

// itemsFromApi is an array, so you either need to get
// itemsFromApi[0] for the first object in the array,
// or if you want to iterate all of the itemsFromApi, you'll
// need to handle that in a loop too.

// If you just want the first itemsFromApi object
  return (
    <div>
      <Table striped>
        <thead>
          <tr>
            <th>#Number</th>
            <th>item</th>
            <th>description</th>
            <th>quantity</th>
            <th>price</th>
          </tr>
        </thead>
        <tbody>
          {itemsFromApi.length > 0 amp;amp; itemsFromApi[0].items amp;amp; itemsFromApi[0].items.map(item => {
            return (
              <tr>
                <th scope="row">{item.id}</th>
                <td>{item.description}</td>
                <td>{item.item}</td>
                <td>{item.quantity}</td>
                <td>{item.price}</td>
              </tr>
            );
          })}
        </tbody>
      </Table>
    </div>
  )

// Or if you want a full table for each of the itemsFromApi objects
  return (
    <div>
      {itemsFromApi.map((itemFromApi) => (
        <Table striped>
          <thead>
            <tr>
              <th>#Number</th>
              <th>item</th>
              <th>description</th>
              <th>quantity</th>
              <th>price</th>
            </tr>
          </thead>
          <tbody>
            {itemFromApi.items amp;amp; itemFromApi.items.map(item => {
              return (
                <tr>
                  <th scope="row">{item.id}</th>
                  <td>{item.description}</td>
                  <td>{item.item}</td>
                  <td>{item.quantity}</td>
                  <td>{item.price}</td>
                </tr>
              );
            })}
          </tbody>
        </Table>
      )}
    </div>
  )
}
 

Комментарии:

1. у меня проблема, когда я пытаюсь использовать ваш способ отображения {items.items amp;amp; items.items.map(item => { вместо длинной версии, которую я использую, она ничего не показывает в таблице (я скопировал ваш же код ) я не знаю, что не так

2. Моя вина. Попробуйте сейчас — я изменил его на item.items , а также переименовал item в rowItem в функции карты, чтобы избежать проблем, потому что вы уже item определили.

3. но у меня есть const [items, setItems] = useState ([]), так что это должны быть items.items, но это все равно так не работает, имена настолько похожи, что они меня так перепутали

4. Если это то, что у вас есть, и тогда ваше состояние items представляет собой массив объектов json , а внутри каждого объекта json находится массив items , мне нужно увидеть больше вашего кода. Потому что код, который я опубликовал, работал бы, если бы вы запустили его для одного из items ваших состояний, но ваше состояние представляет собой массив, поэтому нам не хватает уровня цикла/итерации, который я не могу решить без дополнительной части вашего кода для этого компонента.

5. неужели мне чего-то не хватает