Dasihub
@Dasihub

Как сделать рендер таблицы React js?

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

const [data, setData] = React.useState([
        {county: 'Кыргызстан', contract: 11000, credit: 11, kurs: 1},
        {county: 'Кыргызстан', contract: 12000, credit: 12, kurs: 2},
        {county: 'Кыргызстан', contract: 13000, credit: 13, kurs: 3},
        {county: 'Кыргызстан', contract: 14000, credit: 14, kurs: 4},
        {county: 'Ближнее зарубежье (вход между-ное соглашение)', contract: 21000, credit: 21, kurs: 1},
        {county: 'Ближнее зарубежье (вход между-ное соглашение)', contract: 22000, credit: 22, kurs: 2},
        {county: 'Ближнее зарубежье (вход между-ное соглашение)', contract: 23000, credit: 23, kurs: 3},
        {county: 'Ближнее зарубежье (вход между-ное соглашение)', contract: 24000, credit: 24, kurs: 4},
        {county: 'Дальнее зарубежье', contract: 31000, credit: 31, kurs: 1},
        {county: 'Дальнее зарубежье', contract: 32000, credit: 32, kurs: 2},
        {county: 'Дальнее зарубежье', contract: 33000, credit: 33, kurs: 3},
        {county: 'Дальнее зарубежье', contract: 34000, credit: 34, kurs: 4},
        {county: 'Ближнее зарубежье (не вход между-ное соглашение)', contract: 41000, credit: 41, kurs: 1},
        {county: 'Ближнее зарубежье (не вход между-ное соглашение)', contract: 42000, credit: 42, kurs: 2},
        {county: 'Ближнее зарубежье (не вход между-ное соглашение)', contract: 43000, credit: 43, kurs: 3},
        {county: 'Ближнее зарубежье (не вход между-ное соглашение)', contract: 44000, credit: 44, kurs: 4},
    ])


вот этот данные нужно рендерить и чтобы получилось вот такая таблица
617d470e1a38d485590993.png

import React from "react";

const Document = React.forwardRef((props, ref) => {


    return (
        <div ref={ref}>
        <h1 className="head_doc">Отчет</h1>
        <div className="data_smeta">Смета за 2020-21г учебный год</div>
        <div className="faculties_doc">Высшее образование</div>
        <div className="speciality_doc">Арабский язык(очная бакалавр)(ВПО)</div>
        <table className="table_doc_container">
            <tbody>
            <tr>
                <th className="doc_th">№</th>
                <th className="doc_th">Название</th>
                <th className="doc_th">Курс</th>
                <th className="doc_th">Сумма контракта</th>
                <th className="doc_th">Сумма кредита</th>
            </tr>
            <tr>
                <th className="doc_th">1</th>
                <th className="doc_th">Кыргызстан</th>
                <th className="doc_th">
                    <div className="table_doc_contract">1</div>
                    <div className="table_doc_contract">2</div>
                    <div className="table_doc_contract">3</div>
                    <div>4</div>
                </th>
                <th className="doc_th">
                    <div className="table_doc_contract">30000</div>
                    <div className="table_doc_contract">30000</div>
                    <div className="table_doc_contract">30000</div>
                    <div>30000</div>
                </th>
                <th className="doc_th">
                    <div className="table_doc_contract">70</div>
                    <div className="table_doc_contract">70</div>
                    <div className="table_doc_contract">70</div>
                    <div>70</div>
                </th>
            </tr>
            <tr>
                <th className="doc_th">2</th>
                <th className="doc_th">Ближнее зарубежье (вход между-ное соглашение)</th>
                <th className="doc_th">
                    <div className="table_doc_contract">1</div>
                    <div className="table_doc_contract">2</div>
                    <div className="table_doc_contract">3</div>
                    <div>4</div>
                </th>
                <th className="doc_th">
                    <div className="table_doc_contract">27000</div>
                    <div className="table_doc_contract">27000</div>
                    <div className="table_doc_contract">27000</div>
                    <div>27000</div>
                </th>
                <th className="doc_th">
                    <div className="table_doc_contract">40</div>
                    <div className="table_doc_contract">40</div>
                    <div className="table_doc_contract">40</div>
                    <div>40</div>
                </th>
            </tr>
            <tr>
                <th className="doc_th">3</th>
                <th className="doc_th">Дальнее зарубежье</th>
                <th className="doc_th">
                    <div className="table_doc_contract">1</div>
                    <div className="table_doc_contract">2</div>
                    <div className="table_doc_contract">3</div>
                    <div>4</div>
                </th>
                <th className="doc_th">
                    <div className="table_doc_contract">34000</div>
                    <div className="table_doc_contract">34000</div>
                    <div className="table_doc_contract">34000</div>
                    <div>34000</div>
                </th>
                <th className="doc_th">
                    <div className="table_doc_contract">55</div>
                    <div className="table_doc_contract">55</div>
                    <div className="table_doc_contract">55</div>
                    <div>55</div>
                </th>
            </tr>
            <tr>
                <th className="doc_th">4</th>
                <th className="doc_th">Ближнее зарубежье (не вход между-ное соглашение)</th>
                <th className="doc_th">
                    <div className="table_doc_contract">1</div>
                    <div className="table_doc_contract">2</div>
                    <div className="table_doc_contract">3</div>
                    <div>4</div>
                </th>
                <th className="doc_th">
                    <div className="table_doc_contract">25000</div>
                    <div className="table_doc_contract">25000</div>
                    <div className="table_doc_contract">25000</div>
                    <div>25000</div>
                </th>
                <th className="doc_th">
                    <div className="table_doc_contract">10</div>
                    <div className="table_doc_contract">10</div>
                    <div className="table_doc_contract">10</div>
                    <div>10</div>
                </th>
            </tr>
            </tbody>
        </table>
        </div>
    )
})

export default Document
  • Вопрос задан
  • 246 просмотров
Решения вопроса 2
0xD34F
@0xD34F Куратор тега React
Функция группировки массива по значениям одного из свойств его элементов, она нам ниже не раз понадобится:

const group = (arr, key) =>
  arr.reduce((acc, n) => (
    (acc[n[key]] = acc[n[key]] || []).push(n),
    acc
  ), {});

Имена свойств группируемых данных, они тоже понадобятся:

const groupItemKeys = [ 'kurs', 'contract', 'credit' ];

Вариант раз - выводим значения группы в одной ячейке, то, что, судя по показанному коду, пытались изобразить вы:

const groupedData = useMemo(() => {
  return Object.entries(group(data, 'country'));
}, [ data ]);

<tbody>{groupedData.map(([ country, items ], i) =>
  <tr>
    <td>{i + 1}</td>
    <td>{country}</td>
    {groupItemKeys.map(k =>
      <td>{items.map(n => <div>{n[k]}</div>)}</td>
    )}
  </tr>)}
</tbody>

Вариант два - разбиваем данные группы по разным строкам. Для нулевого элемента группы выводим ячейки с данными, общими для группы, этим ячейкам задаём атрибут rowspan со значением, равным размеру группы:

const groupedData = useMemo(() => {
  return Object.values(group(data, 'country'));
}, [ data ]);

<tbody>{groupedData.map((n, i) => n.map((m, j) =>
  <tr>
    {!j && <React.Fragment>
      <td rowSpan={n.length}>{i + 1}</td>
      <td rowSpan={n.length}>{m.country}</td>
    </React.Fragment>}
    {groupItemKeys.map(k => <td>{m[k]}</td>)}
  </tr>))}
</tbody>

Вариант три - сгруппированные данные разворачиваем обратно в общий массив, дополнив их значениями для атрибута rowspan и отбросив ключи, а при рендере - никаких проверок, никаких обращений к конкретным свойствам:

const rowsData = useMemo(() => {
  return Object
    .values(group(data, 'country'))
    .flatMap((items, i) => items.map((n, j) => (j
      ? []
      : [ i + 1, n.country ].map(m => [ m, items.length ])
    ).concat(groupItemKeys.map(k => [ n[k] ]))));
}, [ data ]);

<tbody>{rowsData.map(n =>
  <tr>{n.map(m => (
    <td rowSpan={m[1]}>{m[0]}</td>))}
  </tr>)}
</tbody>
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы