React-table - presenting data from Context in table

Viewed 842

My application pulls data from an API and presents this data to the user. My table from react-table is just one component that uses this data and so I store the API response in Context. I am able to make this context data available to the table component, and I have a test to make sure the data is available before setting value / rendering, but for some reason the table does not appear.

There is a stackblitz at https://stackblitz.com/edit/react-jvmryf and you can see an example of the behaviour at https://react-jvmryf.stackblitz.io/jinky32/own

The code for my component is below, any help would be much appreciated, I've been fighting this for ages now with no joy! I assume this is because the context data is not set by the time my if statement checks, but how can I wait for it to be set?

import React, { useMemo, useState, useEffect, useContext, useCallback } from 'react';
import { useLocation } from "react-router-dom";
import { useTable, useFilters, useSortBy, useRowSelect } from 'react-table';
import { UserContext } from "../context/UserContext";
import { relatedCardsColumns } from '../helpers/columns'
import { Checkbox } from './Checkbox'
import BTable from 'react-bootstrap/Table';

export const NewTable = () => {

    //const [ownedCardData, setownedCardData] = useState([]);
    const userContext = useContext(UserContext); 

    const columns = useMemo(() => relatedCardsColumns, [])
    let data = [];
    if (userContext.dataLoaded) {.  <--dataLoaded is set to true in context with userContext.data is populated from API response
        console.log("context data loaded")
        data = userContext.data
    }
    data = useMemo(() => data, [])
  
    const {
        getTableProps,
        getTableBodyProps,
        headerGroups,
        rows,
        prepareRow,
        state,
        nextPage,
        previousPage,
        canNextPage,
        canPreviousPage,
        pageOptions,
        setPageSize,
        selectedFlatRows
    } = useTable(
        {
            columns: columns,
            data: ownedCardData
        },
        useFilters,
        useSortBy,
        useRowSelect,
        hooks => {
            hooks.visibleColumns.push(columns => [
                // Let's make a column for selection
                {
                    id: 'selection',
                    // The header can use the table's getToggleAllRowsSelectedProps method
                    // to render a checkbox
                    Header: ({ getToggleAllRowsSelectedProps }) => (
                        <div>
                            <Checkbox {...getToggleAllRowsSelectedProps()} />
                        </div>
                    ),
                    // The cell can use the individual row's getToggleRowSelectedProps method
                    // to the render a checkbox
                    Cell: ({ row }) => (
                        <div>
                            <Checkbox {...row.getToggleRowSelectedProps()} />
                        </div>
                    ),
                },
                ...columns,
            ])
        }
    )
    const { pageIndex, pageSize } = state;

    return (
        <div><p> The data is <b>{userContext.dataLoaded ? <> <p>loaded</p>
            <BTable striped bordered hover size="sm" {...getTableProps()}>
                <thead>
                    {headerGroups.map((headerGroup) => (
                        <tr {...headerGroup.getHeaderGroupProps()}>
                            {headerGroup.headers.map((column) => (
                                <th {...column.getHeaderProps(column.getSortByToggleProps())}>
                                    {column.render("Header")}
                                    <span>
                                        {column.isSorted ? (column.isSortedDesc ? ' ⬇️ ' : ' ⬆️') : ''}
                                    </span>
                                    {/* rendering column filter */}
                                    <div>{column.canFilter ? column.render('Filter') : null}</div> </th>
                            ))}
                        </tr>
                    ))}
                </thead>
                <tbody {...getTableBodyProps()}>
                    {rows.map((row, i) => {
                        prepareRow(row);
                        return (
                            <tr {...row.getRowProps()}>
                                {row.cells.map((cell) => {
                                    return <td {...cell.getCellProps()}>{cell.render("Cell")}</td>;
                                })}
                            </tr>
                        );
                    })}
                </tbody>
            </BTable>
            <select value={pageSize} onChange={(e) => setPageSize(Number(e.target.value))}>
                {[10, 25, 50, 100].map((pageSize) => (
                    <option key={pageSize} value={pageSize}>
                        Show {pageSize}
                    </option>
                ))}
            </select>
            <pre>
                <code>
                    {
                        JSON.stringify(data)
                    }
                </code>
            </pre> </>
            :
            'not'}</b> loaded.</p></div>
    );
};
1 Answers

OK ignore me. I was referencing the wrong variable in { columns: columns, data: ownedCardData },. from a previous refactor

Related