0
votes

I am trying to create material-table with switches, that onclick changes the state of the component.

how it looks Here is component with table, which has state of the parent component as a props. I pass rows variable to the material table data prop. Switch is custom rendered field. Whenever I click on it, it triggers changeRow, which finds index of row in rows variable changes it and saves into new variable. ChangeRows is then called to change the state. The problem is, the switch is not changing. It looks like nothing is happenning, even though I can clearly see new state in console.

const StuffTable = ({rows, changeRows}) => {

const changeRow = (oldRow, e) => {
    const changeData = {[e.target.name]: e.target.checked};
    const newRow = {...oldRow, ...changeData};

    console.log(oldRow, e);

    const index = rows.findIndex(dtaRow => dtaRow.id === oldRow.id);
    const newData = rows;
    newData[index] = newRow;

    console.log(newData);
    changeRows(newData);
};

return (
    <Container maxWidth="lg">
        <Button onClick={() => { changeRow({id: 6}, { target: {name: 'borrowable', checked: true} }) }}>klikni</Button>
        <MaterialTable
            options={{
                actionsColumnIndex: -1,
                search: true,
                exportButton: true,
                exportDelimiter: ";"
            }}
            actions={[
                {
                    icon: 'edit',
                    tooltip: 'Edit Study',
                    onClick: (event, rowData) => alert("Do you want to edit?")
                }]}
            columns={[
                { title: "Název", field: "title" },
                { title: "Stav", field: "status", render: (data) => <Chip label={data.status} color="primary" avatar={<Avatar src="/static/images/avatar/1.jpg" />} /> },
                { title: "Půjčovat", field: "borrowable", render: (data, id) => (<FormControlLabel control={<Switch checked={data.borrowable} onChange={(e) => changeRow(data, e)} name="borrowable" color="primary"/>} label={data.borrowable ? 'půjčovat' : 'nepůjčovat'} />) },
                { title: "Vidí všichni", field: "active", render: (data, id) => (<FormControlLabel control={<Switch checked={data.borrowable} onChange={(e) => changeRow(data, e)} name="borrowable" color="primary"/>} label={data.borrowable ? 'půjčovat' : 'nepůjčovat'} />) },
                { title: "Uskladněno", field: "location" },
            ]}
            data={rows}
            title="Moje věci"
        />
    </Container>
);
};

 export default StuffTable;

console

I tried to add button, which on click changes state to empty array, and table did show nothing. But when I triggered changeRow (mockup data) with this button, result was the same - no change on the switch.

import React, {useEffect, useState} from 'react';

import StuffTable from "../components/stuffTable";

let rows = [ {id:5, title: "prošívanice", borrowable: false, surname: "Baran", status: "zapůjčeno", location: "Praha" }, {id:6, title: "prošívanice 2", borrowable: false, surname: "Baran", status: "zapůjčeno", location: "Praha" }, {id:7, title: "prošívanice 3", borrowable: false, surname: "Baran", status: "zapůjčeno" , location: "Brno"} ];

Here is Parent component

const MyStuffPage = () => {

    const [data, setData] = useState(rows);

    return (
        <div>
            <StuffTable rows={data} changeRows={(data) => {setData(data); console.log("hou",data);}} />
        </div>
    );
};

export default MyStuffPage;

Here is Codesandbox with this problem: https://codesandbox.io/s/festive-gould-i1jf7

1

1 Answers

1
votes

You need to call onQueryChange whenever you want to render new data or state to the datatable, make these changes: at the begining create a ref like so:

const tableRef = useRef(null);

then use it in the material table:

<MaterialTable
   //add this
   tableRef={tableRef}
   options={{
     actionsColumnIndex: -1,
     search: true,
     exportButton: true,
     exportDelimiter: ";"
   }}

then inside your changeRow function after updating the start and the necessary work add this:

tableRef.current.onQueryChange()

this will tell the table to render the new data with the correct state of the switch