0
votes

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

enter image description here

 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> &nbsp; &nbsp; </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>


    &nbsp;&nbsp;&nbsp;
    &nbsp;&nbsp;&nbsp;


    <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 ));
1
You cannot use useState in a class component, only in function component. Instead use setState in class, or convert your class component to function one thus you can utilize useState and other hooks. - norbitrial
You can`t mix react class component with hooks Check this docs for details. - Den Kison
I'm new to this, how can I fix this? - Fatih mzm

1 Answers

1
votes

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()