Updating table after delete (axios, react, express) - reactjs

I'm working on a CRUD app with MySQL, React, Express, and Axios.
This is the last part but I can't seem to figure out how to refresh my table data after the record is deleted. I've tried updating the state in the .then() as well as directly after the function call. If I update the state with a different year/manager it works properly but I would like to just refresh the manager/year data that is currently active. I've never posted a code sample this long so I hope it isn't too much but I really didn't want to miss anything.
Of note, I'm using react-table so the way I handle the "only one checkbox may be selected at a time" is kind of odd.
import { useState, useEffect, useMemo, forwardRef, useRef } from "react";
import axios from "axios";
import { useSortBy, useTable, useRowSelect } from "react-table";
import "./KeeperTable.css";
const KeeperTable = (props) => {
const [playersList, setPlayersList] = useState([]);
const [url, setUrl] = useState("/getData");
const data = useMemo(() => playersList, [playersList]);
const columns = useMemo(
() => [
{
Header: "Manager",
accessor: "manager",
},
{
Header: "Player",
accessor: "player_name",
},
{
Header: "Year",
accessor: "year",
},
{
Header: "Retained",
accessor: "drafts_retained",
},
{
Header: "Remain",
accessor: "drafts_remaining",
},
],
[]
);
const IndeterminateCheckbox = forwardRef(
({ indeterminate, ...rest }, ref) => {
const defaultRef = useRef();
const resolvedRef = ref || defaultRef;
useEffect(() => {
resolvedRef.current.indeterminate = indeterminate;
}, [resolvedRef, indeterminate]);
return (
<>
<input
type="checkbox"
name="myCheckbox"
ref={resolvedRef}
{...rest}
/>
</>
);
}
);
const handleDeleteClick = () => {
let checkedCount = 0;
let manager = "";
let player = "";
let year = "";
//Gets the data from selected row
let rows = document.getElementsByName("myCheckbox");
for (let row of rows) {
row.checked && checkedCount++;
if (row.checked) {
manager = row.parentNode.parentNode.nextElementSibling.innerHTML;
player =
row.parentNode.parentNode.nextElementSibling.nextElementSibling
.innerHTML;
year =
row.parentNode.parentNode.nextElementSibling.nextElementSibling
.nextElementSibling.innerHTML;
}
}
//if more than one row is selected stop, else make the call to deletePlayerRecord
if (checkedCount >= 2 || checkedCount <= 0) {
console.log("only delete one record at a time!");
} else {
async function deletePlayerRecord() {
axios
.post("/deletePlayer", {
year: year,
manager: manager,
player: player,
})
.then((res) => {
setUrl(`/getData/${year}/${manager}`);
});
}
//call the function then update the state which should refresh the table. url variable has a useEffect that updates the playersList date which in turn has a
//use effect to make a new axios call and get the proper data.
console.log("clicked");
deletePlayerRecord();
}
};
const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } =
useTable(
{
columns,
data,
},
useSortBy,
useRowSelect,
(hooks) => {
hooks.visibleColumns.push((columns) => [
// Let's make a column for selection
{
id: "selection",
Header: ({ getToggleAllRowsSelectedProps }) => (
<div>
<button onClick={handleDeleteClick} className="btn-primary">
X
</button>
</div>
),
// The cell can use the individual row's getToggleRowSelectedProps method
// to the render a checkbox
Cell: ({ row }) => (
<div>
<IndeterminateCheckbox {...row.getToggleRowSelectedProps()} />
</div>
),
},
...columns,
]);
}
);
useEffect(() => {
if (props.yearSearch !== "#" && props.teamSearch !== "#") {
setUrl(`/getData/${props.yearSearch}/${props.teamSearch}`);
}
}, [props.yearSearch, props.teamSearch]);
useEffect(() => {
async function getTeams() {
axios.get(url).then((res) => {
setPlayersList(res.data);
});
}
getTeams();
}, [url]);
return (
<div className="flex">
<table id="keepers" {...getTableProps()}>
<thead>
{headerGroups.map((headerGroup) => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map((column) => (
<th {...column.getHeaderProps(column.getSortByToggleProps())}>
{column.render("Header")}
</th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{rows.map((row) => {
prepareRow(row);
return (
<tr {...row.getRowProps()}>
{row.cells.map((cell) => {
return (
<td {...cell.getCellProps()}>{cell.render("Cell")}</td>
);
})}
</tr>
);
})}
</tbody>
</table>
</div>
);
};
export default KeeperTable;
If you would like to see the server side code I can post it but I do not think it is relavent as the delete does work properly it is just the table refreshing after that I can't seem to get.

Related

How to display data from node.js api returning a an array of obect to react.js

I'm trying to get specific values from an array object returned by my node.js api
Here's the array of object returned by my node.js api
[
{
"name": "device1",
"serial": "WMD105222022",
"status": "online"
},
{
"name": "device2q",
"serial": "sdfsdf",
"status": "online"
},
{
"name": "ducs",
"serial": "WMD105222022",
"status": "online"
}
]
Here's my react.js code
import React, {useState, useEffect} from "react";
import './Module.css';
import {SDH} from '../../components';
import {temp, water, humidity, nutrient} from '../../assets';
import Button from 'react-bootstrap/Button';
import Modal from 'react-bootstrap/Modal';
import Form from 'react-bootstrap/Form';
import {Link} from 'react-router-dom';
import Axios from "axios";
const Module = () => {
const [show, setShow] = useState(false);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
const email = sessionStorage.getItem("email");
const [device, setDevice] = useState({});
Axios.defaults.withCredentials = true;
useEffect(() => {
Axios.get("http://localhost:3020/getdevice", {
params: {
email: email
}
})
.then((response) => {
setDevice(response.data);
})
// .then((response) => {},
// (err) => {
// alert("No Data To Show");
// }
// )
.catch((err) => {
return false;
});
},[]);
const DisplayData = () => {
return (
<div>
<td>{device.name}</td>
<td>{device.serial}</td>
<td>{device.status}</td>
</div>
);
};
return (
<div className="MainBodyM">
<SDH/>
<h3 className="deviceStatus"></h3>
{/* <Button onClick={getDevices} variant="primary" type="submit">Refresh List</Button> */}
<div className="tempHeader">
<table>
<tr>
<td>Name</td>
<td>Serial Number</td>
<td>Status</td>
</tr>
<tr>
{DisplayData}
</tr>
</table>
</div>
<Link to="/registerdevice">
<Button>Add Control Module</Button>
</Link>
</div>
);
};
export default Module;
I needed to get the name, serial, and status to be displayed in a table. up until now i'm still getting nowhere, please help, i'm only using {JSON.stringify(device, null, 3)} to display the returned array of object that's why i know i'm getting an array of object. I'm open to suggestions and correction. Thank you.
I need the output to be like this, regardless how many devices/data i add in array of object.
Device Serial Status
Device1 121 online
device2 234135 offline
balcony ash3 online
bathroom dsgfkahaskj23 online
so on... tj2l5 offline
You must send an array from the backend. You must send a JSON
In express
app.get("/test", (req, res) => {
res.json({
array: [
{
name: "device1",
serial: "WMD105222022",
status: "online",
},
{
name: "device2q",
serial: "sdfsdf",
status: "online",
},
{
name: "ducs",
serial: "WMD105222022",
status: "online",
},
],
});
});
Note that I send a JSON, not an array
In React:
const [data, setData] = useState([]);
useEffect(() => {
var config = {
method: "get",
url: "http://localhost:3000/test",
headers: {},
};
axios(config)
.then(function (response) {
const data = JSON.stringify(response.data);
const array = JSON.parse(data).array;
setData(array);
})
.catch(function (error) {
console.log(error);
});
}, []);
Note that I convert the JSON to an object to be able to iterate it
the return on the component
<table>
{data &&
data.map((row, key) => {
return (
<tr key={key} style={{ color: "red" }}>
<td>{row.name}</td>
<td>{row.serial}</td>
<td>{row.status}</td>
</tr>
);
})}
</table>
You can extract the columns name, ie. "Device", "Serial", "Status", into an array, and iterate over them using map function:
const [data, setDate] = useState();
const columns = ["Device", "Serial", "Status"]; // hard code the columns
const lookUpDataKey = {
Device: "name",
Serial: "serial",
Status: "status"
};
useEffect(() => {
setDate(dataFromApi); // mimic getting data from api
}, []);
if (!data) return <div>loading</div>;
return (
<div className="App">
<div style={{ display: "flex" }}>
{columns.map((column, columnIndex) => (
<div key={columnIndex}>
{/* Column name */}
<div>{columns[columnIndex]}</div>
{/* Column data */}
{data.map((item, dataIndex) => (
<div key={dataIndex}>
<div>{item[lookUpDataKey[column]]}</div>
</div>
))}
</div>
))}
</div>
</div>
);
Notice we use a lookUpDataKey object for matching column's name to the corresponding object key.
Try it out in updated sandbox.

How to console.log the

I have a simple React component and inside of it I am fetching data from a remote API, and I want to console.log it in useEffect. I am trying to do it but nothing doesn't get logged into the console, why? What am I missing here? Here is the component:
import React, { useState, useEffect } from 'react';
import { useLocalization } from '#progress/kendo-react-intl';
import { Card, CardHeader, Avatar, CardTitle, CardSubtitle } from '#progress/kendo-react-layout';
import { guid } from '#progress/kendo-react-common';
import { Scheduler } from './../components/Scheduler';
import { employees } from './../resources/employees';
import { images } from './../resources/images';
import { orders, ordersModelFields } from './../resources/orders';
import { teams } from './../resources/teams';
// const orderEmployees = employees.filter(employee => employee.jobTitle === 'Sales Representative');
// const initialFilterState = { };
// orderEmployees.forEach(employee => {
// if(employee.fullName === 'Wait Peperell') {
// initialFilterState[employee.id] = false;
// } else {
// initialFilterState[employee.id] = true;
// }
// });
const Planning = () => {
const localizationService = useLocalization();
const [filterState, setFilterState] = React.useState(initialFilterState);
const [data, setData] = React.useState(orders);
const [fetchedData, setFetchedData] = React.useState(null);
useEffect(() => {
fetch("https://mocki.io/v1/29b83c0b-1a55-430d-a173-92b3632e04aa")
.then(response => response.json())
// 4. Setting *dogImage* to the image url that we received from the response above
.then(data => setFetchedData(data))
console.log(fetchedData)
},[])
// console.log(fetchedData)
const onDataChange = React.useCallback(
({ created, updated, deleted }) => {
setData(old => old
// Filter the deleted items
.filter((item) => deleted.find(current => current[ordersModelFields.id] === item[ordersModelFields.id]) === undefined)
// Find and replace the updated items
.map((item) => updated.find(current => current[ordersModelFields.id] === item[ordersModelFields.id]) || item)
// Add the newly created items and assign an `id`.
.concat(created.map((item) => Object.assign({}, item, { [ordersModelFields.id]: guid() }))))
},
[]
);
const onEmployeeClick = React.useCallback(
(employeeId) => {
setFilterState({
...filterState,
[employeeId]: !filterState[employeeId]
});
},
[filterState, setFilterState]
);
return (
<div id="Planning" className="planning-page main-content">
<div className="card-container grid">
<h3 className="card-title">{localizationService.toLanguageString('custom.teamCalendar')}</h3>
{
orderEmployees.map(employee => {
return (
<div
key={employee.id}
onClick={() => onEmployeeClick(employee.id)}
style={!filterState[employee.id] ? {opacity: .5} : {}}
>
<Card style={{ borderWidth: 0, cursor: 'pointer'}}>
<CardHeader className="k-hbox" >
<Avatar type='image' shape='circle' size={'large'} style={{
borderWidth: 2,
borderColor: teams.find(({teamID}) => teamID === employee.teamId).teamColor,
}}>
<div className="k-avatar-image" style={{
backgroundImage: images[employee.imgId + employee.gender],
backgroundSize: 'cover',
backgroundPosition: 'center center',
}}
/>
</Avatar>
<div>
<CardTitle style={{color: teams.find(({teamID}) => teamID === employee.teamId).teamColor}}>{employee.fullName}</CardTitle>
<CardSubtitle>{employee.jobTitle}</CardSubtitle>
</div>
</CardHeader>
</Card>
</div>
);
})
}
<div className="card-component" >
<Scheduler
data={data.filter(event => filterState[event.employeeID])}
onDataChange={onDataChange}
modelFields={ordersModelFields}
resources={[
{
name: 'Teams',
data: teams,
field: 'teamID',
valueField: 'teamID',
textField: 'teamName',
colorField: 'teamColor'
}
]}
/>
</div>
</div>
</div>
);
}
export default Planning;
I also tried to place the console.log outside of useEffect but still, nothing gets console.logged.
You need to look how useEffect work, setFetchedData is async.
Create another useEffect only for console.log.
useEffect(() => {
console.log(fetchedData);
},[fetchedData]); // Update at the first render + when fetchedData state change.
You can do it like this
useEffect(() => {
fetch("https://mocki.io/v1/29b83c0b-1a55-430d-a173-92b3632e04aa")
.then((response) => response.json())
// 4. Setting *dogImage* to the image url that we received from the response above
.then((data) => {
setFetchedData(data);
console.log(data);
});
}, []);
or juste create another useEffect that listens to fetchedData change, like this
useEffect(() => {
console.log(fetchedData);
}, [fetchedData]);

react table select rows - programmatically select rows based on input props

I have created a react table with select rows following this example.
I'm trying to modify it so that when the data loads, the corresponding checkbox is either checked or unchecked based on the row data's included value. The value doesn't seem to be recognized and when I check/uncheck a row the onChange console.log event isn't being fired. What am I doing wrong.
Heres my Sandbox Example
DATA
[
{
systemId: 13,
deqId: "25007",
facilityId: 6487,
sourceId: "WS002",
sourceName: "GROVE SPRING",
flowRate: 461,
flowUom: "GPM ",
included: true
},
{
systemId: 13,
deqId: "25007",
facilityId: 4742,
sourceId: "WS004",
sourceName: "WELL #1",
flowRate: 1100,
flowUom: "GPM ",
included: true
},
{
systemId: 13,
deqId: "25007",
facilityId: 4743,
sourceId: "WS005",
sourceName: "100 W (WELL #2) ",
flowRate: 800,
flowUom: "GPM ",
included: true
},
{
systemId: 13,
deqId: "25007",
facilityId: 4744,
sourceId: "WS007",
sourceName: "NORTH (WELL #3) ",
flowRate: 900,
flowUom: "GPM ",
included: true
}
];
INDETERMINATE CHECKBOX
const IndeterminateCheckbox = React.forwardRef(
({ indeterminate, checked, name, ...rest }, ref) => {
const defaultRef = React.useRef(checked);
const resolvedRef = ref || defaultRef;
React.useEffect(() => {
resolvedRef.current.indeterminate = indeterminate;
resolvedRef.current.checked = checked;
}, [resolvedRef, indeterminate, checked]);
return (
<>
<input
type="checkbox"
ref={resolvedRef}
checked={checked}
name={name}
id={name}
{...rest}
/>
</>
);
}
);
REACT TABLE
function ReactTable({
columns,
data,
handleCheckboxSelection,
handleCheckboxStateChange
}) {
// Use the state and functions returned from useTable to build your UI
const {
getTableProps,
getTableBodyProps,
headerGroups,
footerGroups,
rows,
prepareRow,
selectedFlatRows
} = useTable(
{
columns,
data
},
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 },
handleCheckboxStateChange
) => (
<div>
<IndeterminateCheckbox {...getToggleAllRowsSelectedProps()} />
</div>
),
// The cell can use the individual row's getToggleRowSelectedProps method
// to the render a checkbox
Cell: ({ row }) => (
<div>
<IndeterminateCheckbox
name={row.original.sourceId}
onChange={(row) => console.log(row.original)} //not firing
checked={row.original.included}
{...row.getToggleRowSelectedProps()}
/>
</div>
)
},
...columns
]);
}
);
// Render the UI for your table
return (
<>
<table {...getTableProps()}>
<thead>
{headerGroups.map((headerGroup) => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map((column) => (
<th {...column.getHeaderProps()}>{column.render("Header")}</th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{rows.slice(0, 10).map((row, i) => {
prepareRow(row);
return (
<tr {...row.getRowProps()}>
{row.cells.map((cell) => {
return (
<td {...cell.getCellProps()}>{cell.render("Cell")}</td>
);
})}
</tr>
);
})}
</tbody>
<tfoot>
{footerGroups.map((group) => (
<tr {...group.getFooterGroupProps()}>
{group.headers.map((column) => (
<td {...column.getFooterProps()}>
<b>{column.render("Footer")}</b>
</td>
))}
</tr>
))}
</tfoot>
</table>
<button onClick={() => handleCheckboxSelection(selectedFlatRows)}>
Save
</button>
</>
);
}
TABLE IMPLEMENTATION
const MyDataTable = ({
data
}) => {
const handleCheckboxSelection = (array) => {
console.log(array.map((d) => d.original));
};
const columns = React.useMemo(
() => [
{
Header: "Source ID",
accessor: "sourceId"
},
{
Header: "Source Name",
accessor: "sourceName"
},
{
Header: "Flow Rate (GPM)",
accessor: (d) => {
return d.flowRate ? numberWithCommas(d.flowRate) : "";
}
}
],
[]
);
return (
<ReactTable
columns={columns}
data={data}
handleCheckboxSelection={handleCheckboxSelection}
/>
);
};
The props you added to IndeterminateCheckbox are being overwritten. row.getToggleRowSelectedProps() returns an object:
{
onChange: function,
checked: Boolean,
title: String,
indeterminate: Boolean,
style: Object
}
which overwrites your properties.
The correct way to do what you want to do would be to use
initialState.selectedRowIds property from the useRowSelect API.
Map your data to their included values, then add that array to the initialState as selectedRowIds. In ReactTable.js:
const selectedRowIds = data.map((d, ind) => d.included)
const {
// etc
} = useTable(
{
columns,
data,
initialState: {selectedRowIds}
},
//etc
...columns
}
);
you have to refresh your Table.
you can use useState.
example : you can add onClick={this.mychange} to your save Button.
mychange = async () => {
this.setState({
List: //the new List Data
})
}
and dont forget the Constructor.
constructor() {
super();
this.state = {
List: anyList,
};
}

how should I re-draw table component with entered value

I am trying to call an API with given value for drawing data table.
Here is what I want to do and How the actual code works.
How should I fix it? please I need your kind advice.
what I want to do
draw a table with initial value(with 5 rows).
type 2 and click submit button for re-drawing table(with 2 rows)
the table should be given with 2 rows.
How the actual code works
draw a table with initial value(with 5 rows).
type 2 and click submit button for re-drawing table(with 2 rows).
the table is given with 5 rows.
my main code
import React, { useEffect, useState } from 'react';
import Table from 'components/advTable';
import { apiProvider } from 'services/modules/provider';
import {
CBadge,
CDataTable,
CCard,
CCardBody,
CCardHeader,
CCol,
CFormGroup,
CInput,
CLabel,
CSelect,
CRow,
CCardFooter,
CButton,
} from '#coreui/react'
import CIcon from '#coreui/icons-react'
const PendingVertification = () => {
const [query, setQuery] = useState(5);
const [info, setInfo] = useState({});
const [page, setPage] = useState(1);
const [countPerPage, setCountPerPage] = useState(5);
const subURL = "users";
const onChange = (e : any) => {
console.log('the Value: ', e.target.value);
//if I enter number 2 and setQuery(2)
setQuery(e.target.value.toLowerCase());
};
const onSubmit = (e : any) => {
e.preventDefault();
//Call API to draw a table
getTableList();
//setQuery(5);
};
const getTableList = () => {
//Call API for table Data with Given values.
apiProvider.getTabledata(page, query, subURL ).then(res => {
setInfo(res.data);
}).catch(err => {
setInfo({});
});
}
useEffect(() => {
//Call Rest API only once
getTableList();
}, []);
return (
<>
<CRow>
<CCol xs="12" lg="15">
<CCard>
<CCardHeader>
Sample
<small> Form</small>
</CCardHeader>
<CCardBody>
<CRow>
<CCol xs="12">
<CFormGroup>
<CLabel htmlFor="ccnumber">Search Value</CLabel>
<CInput id="ccnumber" placeholder="fill this form" onChange={onChange} required />
</CFormGroup>
</CCol>
</CRow>
</CCardBody>
<CCardFooter>
<CButton type="submit" size="sm" color="primary" onClick={onSubmit}><CIcon name="cil-scrubber"/> Submit</CButton>
<CButton type="reset" size="sm" color="danger"><CIcon name="cil-ban" /> Reset</CButton>
</CCardFooter>
</CCard>
</CCol>
</CRow>
{info && <Table tableData={info} query={query} subURL = {subURL}/>}
</>
//the code above Draws table with given values
);
};
export default PendingVertification;
Table component code
import React, { useEffect, useState, useRef } from 'react';
import DataTable from 'react-data-table-component';
import { apiProvider } from 'services/modules/provider';
interface Props {
tableData: any,
query: number,
subURL: string
}
const Table: React.FunctionComponent<Props> = ({ tableData, query, subURL}) => {
const columns = [
{
name: tableData.mata? tableData.meta.firstColum : 'Avatar',
cell: (row : any) => <img height="30px" width="30px" alt={row.first_name} src={row.avatar} />
},
{
name: tableData.mata? tableData.meta.secondColum : 'First Name',
selector: 'first_name'
},
{
name: tableData.mata? tableData.meta.thirdColum : 'Last Name',
selector: 'last_name'
},
{
name: tableData.mata? tableData.meta.fourthColum : 'e-mail',
selector: 'email'
}
];
//set The value for drawing table
// countPerpage should be 2 when I enter 2 but it always contain number 5.
const [page, setPage] = useState(1);
const [countPerPage, setCountPerPage] = useState(query);
const [users, setUsers] = useState<any>({tableData});
const isMounted = useRef(false);
const getTableList = async () => {
//re-draw table with give values.
const response = await apiProvider.getTabledata(page, countPerPage, subURL);
setUsers(response);
}
useEffect(() => {
if(isMounted.current) {
getTableList();
} else {
isMounted.current = true;
}
}, [page, countPerPage, tableData]);
return (
<>
<DataTable
title="Table (Server side Pagination)"
columns={columns}
data={users.data}
highlightOnHover
pagination
paginationServer
paginationTotalRows={users.total}
paginationPerPage={countPerPage}
paginationRowsPerPageOptions={[5, 10, 15, 25, 50]}
paginationComponentOptions={{
noRowsPerPage: false
}}
onChangeRowsPerPage= { rowsPerPage => setCountPerPage(rowsPerPage)}
onChangePage={page => setPage(page)}
/>
</>
);
};
export default Table;
Try this in Table component:
//New useEffect, keep your other one
useEffect(() => {setCountPerPage(query)}, [query])

I get an error when using reactjs useState

I am using reactjs. I am using the material-table to get the data with the editable table.
But I get an error like the picture, how can I fix this error?
I use useState for the edit settings of the table.
Please can you help with the error?
I do not receive any errors while receiving data. I just use editing on the table as active / inactive.
But
     const [, forceUpdate] = useState (false);
     const [data, setData] = useState (drBounty);
gives error for lines.
screenshot of the error and my source code below
import React, { Component, useState } from "react";
import withAuth from "../../components/helpers/withAuth";
import AlertMessageBox from "../../components/helpers/AlertMessageBox";
import { connect } from "react-redux";
import { Button, Col, Row, Table, Input } from "reactstrap";
import MaterialTable, { MTableEditRow } from "material-table";
import icons from '#material-ui/core/Icon';
import DeleteOutline from '#material-ui/icons/DeleteOutline';
import Edit from '#material-ui/icons/Edit';
class Bounty extends Component {
constructor(props) {
super(props);
this.state = {
isLoaded: true,
drBounty: [],
drList: [],
columns: [
{ title: 'Name', field: 'doctorName',
cellStyle:{padding: "1px", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", maxWidth: "1px"},
editComponent: (props) => (
<Input
type="text"
placeholder={props.columnDef.title}
defaultValue={props.value}
onChange={(e) => props.onChange(
this.setState({
doctorName: e.target.value
})
)}
/>
)
},
{ title: 'LastName', field: 'doctorLastName',
cellStyle:{padding: "1px", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", maxWidth: "5px"},
editComponent: (props) => (
<Input
type={"text"}
placeholder={"Doktor soyadı"}
defaultValue={props.value}
onChange={(e) => props.onChange(
this.setState({
doctorLastName: e.target.value
})
)}
/>
)
}
]
};
this.getBountyList = this.getBountyList.bind(this);
}
async componentDidMount() {
await fetch(
`${this.domain}/api/user/groupusers?groupCode=`+
this.props.account_profile.profile.profile.groupCode,
{
headers: {
Authorization: `Bearer ${localStorage.getItem("id_token")}`,
"Content-Type": "application/json"
}
}
)
.then(res => {
if (res.ok) {
return res.json();
} else {
return res.json().then(err => Promise.reject(err));
}
})
.then(json => {
console.log(json)
})
.catch(error => {
console.log(error)
return error;
});
}
async getBountyList(id) {
await fetch(`${this.domain}/api/bounty/list?groupCode=${this.props.account_profile.profile.profile.groupCode}&doctor=${id}`,{
headers: {
Authorization: `Bearer ${localStorage.getItem("id_token")}`,
"Content-Type": "application/json"
}
})
.then(res => {
console.log(res);
if (res.ok) {
return res.json();
} else {
return res.json().then(err => Promise.reject(err));
}
})
.then(json => {
console.log(json)
})
.catch(error => {
console.log(error);
return error;
});
}
render() {
const {isLoaded, drList, drBounty} = this.state;
const [, forceUpdate] = useState(false);
const [data, setData] = useState(drBounty);
const isRowUpdating = (rowData, status) => {
rowData.tableData.editing = status ? "update" : undefined;
forceUpdate(status);
};
if (!isLoaded) {
return <div>Loading...</div>;
} else {
return (
<div className={"animated fadeIn "}>
<Row>
<div> </div>
<Col sm={{span:1, offset:0.9}}>
<Table>
<thead>
<tr>
<th width={"20"} />
<th width={"50"}>Adı</th>
<th width={"70"}>Soyadı</th>
</tr>
</thead>
<tbody>
{
drList
.map(item => (
<tr key={item.id}>
<td>
<Button
block
outline
color="info"
onClick={() => this.getBountyList(item.id)}
>
Aç
</Button>
</td>
<td>{item.first_name} </td>
<td>{item.last_name}</td>
</tr>
))}
</tbody>
</Table>
</Col>
<MaterialTable
Icons={icons}
style={{height: "50", width: "50"}}
columns={ this.state.columns }
data={ this.state.drBounty }
actions={[
rowData => ({
icon: Edit,
tooltip: "Edit row",
onClick: (event, rowData) => {
isRowUpdating(rowData, true);
this.setState({
id: rowData.id,
user: rowData.user,
doctor: rowData.doctor,
doctorName: rowData.doctorName,
doctorLastName: rowData.doctorLastName,
totalBounty: rowData.totalBounty,
description: rowData.description,
customerName: rowData.customerName,
bountyDate: rowData.bountyDate,
createdDate: rowData.createdDate,
groupCode: rowData.groupCode
});
}
})
]}
components={{
EditRow: props => {
const newRowData = {
...drBounty, // *MUST INCLUDE tableData FROM ORIGINAL props.data!!*
id: "DEFAULT VALUES", // <-- // Set whatever default data you want here
doctorName: "ON EDIT" // <-- // (or pull from state, etc.. whatever you want)
};
return (
<MTableEditRow
{...props}
data={newRowData}
onEditingCanceled={(mode, rowData) => {
isRowUpdating(rowData, false);
}}
onEditingApproved={(mode, newData, oldRowData) => {
const dataCopy = [...drBounty];
const index = drBounty.indexOf(props.data);
dataCopy[index] = newData;
setData(dataCopy);
isRowUpdating(props.data, false);
}}
/>
);
}
}}
/>
</Row>
</div>
);
}
}
}
export default connect(withAuth( Bounty ));
You are trying to use the Hook (useState()) inside the render() method. Hooks can only be used inside of function components. However, you are using a class component so you have no need of this Hook.
Suggested Reading: https://reactjs.org/docs/hooks-state.html
Instead of using a Hook, you can use the following in your class component to accomplish the same results. Let's have a look :)
Initialize State in Constructor
this.state = { foo: bar };
You have already done this!
Update State with this.setState()
const [data, setData] = useState(drBounty);
Becomes ..
this.setState({data:drBounty});
However, you want to update the drBounty prop that you set up in the constructor, so you will want something more like this ..
this.setState({drBounty:someData})
Since that prop is an array, you will most likely want to spread (...) that data using the current array.
Re-Render without Updating State
As for your other implementation of useState() it appears you want to re-render without making any updates to state.
const [, forceUpdate] = useState(false);
However, instead you will want to simply use ...
this.render()

Resources