#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. неужели мне чего-то не хватает