[React] DataTable.isDataTable() not working?

[React] DataTable.isDataTable() not working?

chocchoc Posts: 103Questions: 12Answers: 9
edited September 12 in Free community support

Link to test case: https://stackblitz.com/edit/datatables-net-react-simple-2t2khp?file=src%2FApp.tsx
Debugger code (debug.datatables.net):
Error messages shown:
Description of problem: I want to reinitialize the table since I may have different table headers to render.
Before I was using the DataTable.isDataTable() to detect if the table is initialized before:

        if ($.fn.DataTable.isDataTable('#example')) {
            $('#example').DataTable().clear().destroy();

            // since headers will change
            $("#example thead").remove();
            $('#example tbody').remove();
        }

This works very good but in React, I use:

const table = useRef(null);
    useEffect(() => {

        if ($.fn.DataTable.isDataTable($(table.current))) {
            $(table.current).DataTable().clear().destroy();

            // since headers will change
            $(table.current).find('thead').remove();
            $(table.current).find('tbody').remove();
        }
    }, [tableData]);

The DataTable.isDataTable() is always return false! Even with id passed to the <DataTable>:

useEffect(() => {
    if ($.fn.DataTable.isDataTable('#example')) {
        $('#example').DataTable().clear().destroy();

        // since headers will change
        $("#example thead").remove();
        $('#example tbody').remove();
    }
}, [tableData]);


<DataTable
        id="example"
        className="display"
        data={tableData}
        columns={columns}
>
</DataTable>

Am I doing something wrong or is it not supported in React?

Answers

  • chocchoc Posts: 103Questions: 12Answers: 9
    edited September 12

    Or more intuitively if it can automatically react to the data changes including the columns (headers), that would be great so we don't need to manually destroy the table and the thead and tbody

    https://datatables.net/manual/react#Reactive-data

    I also tried to set the option destroy to true but it seems not working as well.

  • allanallan Posts: 63,691Questions: 1Answers: 10,500 Site admin

    The id property isn't used on the JSX element, so it isn't propagated to the DOM element, thus it will always return false.

    Sounds like a good idea for an enhancement though.

    Allan

  • chocchoc Posts: 103Questions: 12Answers: 9

    Hi Allan,

    Thanks for the hint. I have added the id property in the source code. DataTable.isDataTable()` is returned normally as a result. But after the call of:

        if ($.fn.DataTable.isDataTable('#example')) {
            $('#example').DataTable().clear().destroy();
    
            // since headers will change
            $("#example thead").remove();
            $('#example tbody').remove();
        }
    

    before the data changes, the entire table is not reinitialized normally.

    And then I found a solution that is much, much simpler than I thought.

    No need to destroy the table and remove the thead and the tbody.

    Just simply add a key to the <DataTable>

    e.g.

    import DataTable from 'datatables.net-react';
    import DT from 'datatables.net-dt';
    import 'datatables.nt-responsive-dt';
    import 'datatables.net-select-dt';
    
    DataTable.use(DT);
    
    function App() {
      const columns = [
        { data: 'name' },
        { data: 'position' },
        { data: 'office' },
        { data: 'extn' },
        { data: 'start_date' },
        { data: 'salary' },
      ];
    
        return (
            <DataTable
                key={JSON.stringify(columns)} // Add this key prop
                ajax="/data.json"
                columns={columns}
                className="display"
                options={{
                    responsive: true,
                    select: true,
                }}
            >
                <thead>
                <tr>
                    <th>Name</th>
                    <th>Position</th>
                    <th>Office</th>
                    <th>Extn.</th>
                    <th>Start date</th>
                    <th>Salary</th>
                </tr>
                </thead>
            </DataTable>
        );
    }
    
    export default App;
    

    React will unmount for us when the columns are changed. So no more errors! Cheers!

  • allanallan Posts: 63,691Questions: 1Answers: 10,500 Site admin

    Awesome - nice tip!

  • chocchoc Posts: 103Questions: 12Answers: 9
    edited September 13

    Hi Allan,

    also in order to remove the warning message using React development mode:

    Warning: validateDOMNesting(...): Whitespace text nodes cannot appear as a child of <table>. Make sure you don't have any extra whitespace between tags on each line of your source code.
        at table
        at div
        at DataTable (
    

    in the datatables.net-react:

        return (
            <div>
                <table ref={tableEl} className={props.className ?? ''}>
                    {props.children ?? ''}
                </table>
            </div>
        );
    

    should be changed to

        return (
            <div>
                <table ref={tableEl} className={props.className ?? ''}>
                    {props.children ?? null}
                </table>
            </div>
        );
    

    or

        return (
            <div>
                <table ref={tableEl} className={props.className ?? ''}>
                    {props.children}
                </table>
            </div>
        );
    

    The warning message will disappear then.

  • allanallan Posts: 63,691Questions: 1Answers: 10,500 Site admin

    Thank you! Fix committed and will be published with the next release.

    Allan

Sign In or Register to comment.