【问题标题】:I get an error when using reactjs useState使用 reactjs useState 时出现错误
【发布时间】:2020-03-22 19:20:22
【问题描述】:

我正在使用 reactjs。我正在使用材料表来获取带有可编辑表的数据。 但是我得到一个像图片一样的错误,我该如何解决这个错误?

我将 useState 用于表格的编辑设置。 请问您能帮忙解决错误吗?

我在接收数据时没有收到任何错误。我只是将表格上的编辑用作活动/非活动。 但 const [, forceUpdate] = useState (false); const [data, setData] = useState (drBounty);

给出行错误。

下面的错误截图和我的源代码

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

【问题讨论】:

  • 不能在类组件中使用useState,只能在函数组件中使用。而是在类中使用setState,或者将您的类组件转换为函数之一,这样您就可以使用useState 和其他钩子。
  • 您不能将 React 类组件与钩子混合使用查看此docs 了解详细信息。
  • 我是新手,我该如何解决?

标签: reactjs react-native material-ui


【解决方案1】:

您正在尝试在 render() 方法中使用 Hook (useState())。挂钩只能在function components 内部使用。但是,您使用的是class component,因此您不需要此 Hook。 推荐阅读:https://reactjs.org/docs/hooks-state.html


您可以在 class component 中使用以下代码来代替使用 Hook 来实现相同的结果。让我们看看:)

在构造函数中初始化状态

this.state = { foo: bar };

你已经这样做了!

使用 this.setState() 更新状态

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

变成..

this.setState({data:drBounty});

但是,你想更新你在构造函数中设置的 drBounty 属性,所以你会想要更像这样的东西..

this.setState({drBounty:someData})

由于该道具是一个数组,您很可能希望使用当前数组传播(...)该数据。

在不更新状态的情况下重新渲染

至于您的其他 useState() 实现,您似乎想要重新渲染而不对状态进行任何更新。

const [, forceUpdate] = useState(false);

但是,您可能只想使用 ...

this.render()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-11
    • 2020-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-05
    • 2022-06-18
    • 1970-01-01
    相关资源
    最近更新 更多