错误:元素类型无效:在尝试更新状态时,应在反应中出现字符串
Posted
技术标签:
【中文标题】错误:元素类型无效:在尝试更新状态时,应在反应中出现字符串【英文标题】:Error: Element type is invalid: expected a string in react ,when trying to update state 【发布时间】:2020-10-22 21:14:13 【问题描述】:从 fetch 更新状态时出现此错误。
错误:元素类型无效:应为字符串(对于内置组件)或类/函数(对于复合组件),但得到:未定义。您可能忘记从定义组件的文件中导出组件,或者您可能混淆了默认导入和命名导入。
这是我下面的代码
import React from "react"
import useState from "react"
import
Button,
Progress,
UncontrolledDropdown,
DropdownMenu,
DropdownToggle,
DropdownItem,
Input,
Badge,
Row,
Col,
ListGroup,
ListGroupItem
from "reactstrap";
import Draggable from 'react-draggable'
import StatisticsCard from "../../components/@vuexy/statisticsCard/StatisticsCard"
import DataTable from "react-data-table-component"
import classnames from "classnames"
import ReactPaginate from "react-paginate"
import history from "../../history"
import
Edit,
Trash,
ChevronDown,
Plus,
Check,
ChevronLeft,
ChevronRight,
Monitor,
UserCheck,
Mail,
Eye,
MessageSquare,
ShoppingBag,
Heart,
Smile,
Truck,
Cpu,
Server,
Activity,
AlertOctagon,
CreditCard,
Share,
Image
from "react-feather"
import connect from "react-redux"
import
getData,
getInitialData,
deleteData,
updateData,
addData,
filterData
from "../../redux/actions/data-list/"
import Sidebar from "./DataListSidebar"
import Chip from "../../components/@vuexy/chips/ChipComponent"
import Checkbox from "../../components/@vuexy/checkbox/CheckboxesVuexy"
import "../../assets/scss/plugins/extensions/react-paginate.scss"
import "../../assets/scss/pages/data-list.scss"
import Modal, ModalHeader, ModalBody, ModalFooter from 'reactstrap';
import NumberFormat from 'react-number-format';
import $ from 'jquery'
import tc from 'thousands-counter';
class DataListConfig extends React.Component
constructor(props)
super(props)
this.state =
data: [],
campaigns: [],
tt: 0,
totalPages: 0,
currentPage: 0,
columns: [
name: "Name",
selector: "name",
sortable: true,
cell: row => (
<p title=row.name className="text-truncate text-bold-500 mb-0">
sessionStorage.Name
</p>
)
,
name: "Title",
selector: "title",
sortable: true,
cell: row => (
<p className="text-bold-500 text-truncate mb-0">row.title</p>
)
,
name: "Total Donation",
selector: "totaldonor",
sortable: true,
cell: row => (
<p className="text-bold-500 text-truncate mb-0"> <NumberFormat value=row.amounts displayType='text' thousandSeparator=true prefix='₦' /></p>
)
,
name: "Status",
selector: "status",
sortable: true,
cell: row => (
<Badge
color=row.status === null || row.status === '' ? "light-danger" : "light-success"
pill>
row.status === null || row.status === '' ? "Pending":"Active"
</Badge>
)
,
name: "Start Date",
selector: "startdate",
sortable: true,
cell: row => <p className="text-bold-500 mb-0">row.startdate</p>
,
name: "Category",
selector: "category",
sortable: true,
cell: row => <p className="text-bold-500 mb-0">row.category</p>
,
name: "Actions",
sortable: true,
cell: row => (
<this.ActionsComponent
row=row
getData=this.props.getData
parsedFilter=this.props.parsedFilter
currentData=this.handleCurrentData
deleteRow=this.handleDelete
/>
)
],
allData: [],
value: "",
comments:[],
rowsPerPage: 4,
sidebar: false,
currentData: null,
selected: [],
totalRecords: 0,
sortIndex: [],
addNew: ""
const headers = 'Content-Type': 'application/json' , 'Authorization':`Bearer $sessionStorage.jwt`
fetch(' ', headers )
.then(response => response.json())
.then(data =>
this.setState( data: data.posts )
).catch((error) =>
console.log(error)
);
componentDidMount()
function ActionsComponent(props)
const
buttonLabel,
className
= props;
const [modal, setModal] = useState(false);
const [modal2, setModal2] = useState(false);
const [items, setItems] = useState([]);
const [comments,setCom] = useState([])
const Details = (id)=>
$.post(' ',
postid: id
,function(data,status)
setItems([
...items,
datas: data
]);
)
$.post(' ',
postid: props.row.id
,function(data,status)
this.setState(commets: data)
)
let datas
datas = totaldonors: "",totalcomments:""
items.map((key)=>
datas = key.datas
)
const dashdata = datas
const toggleModal = (id) => setModal(!modal); ;
const toggleModal2 = (id) => setModal2(!modal2); ;
return (
<div>
<Draggable>
<Modal
isOpen=modal
toggle=toggleModal
className="modal-dialog-centered"
backdrop=false
>
<ModalHeader toggle=toggleModal>
Campaign Dashboard!
</ModalHeader>
<ModalBody className="modal-dialog-centered">
<div className="container">
<div className="row">
<div className="col-sm">
<StatisticsCard
hideChart
iconBg="primary"
icon=<CreditCard className="primary" size=22 />
stat=tc(dashdata.totaldonors)
statTitle="Total Donors"
/>
</div>
<div className="col-sm">
<StatisticsCard
hideChart
iconBg="primary"
icon=<Share className="primary" size=22 />
stat="36.9k"
statTitle="Total Shares"
/>
</div>
<div className="col-sm">
<StatisticsCard
hideChart
iconBg="primary"
icon=<MessageSquare className="primary" size=22 />
stat=tc(dashdata.totalcomments)
statTitle="Total Comments"
/>
</div>
<div className="container" style='max-height':'300px','overflow-y': 'scroll'>
</div>
</div>
</div>
</ModalBody>
<ModalFooter>
<Button color="primary">
Request Withdrawal
</Button>" "
</ModalFooter>
</Modal>
</Draggable>
<div className="data-list-action">
" "
" "
<Edit
className="cursor-pointer mr-1"
size=20
onClick=() =>
return props.currentData(props.row)
/>
<Activity
className="cid cursor-pointer mr-1"
size=20
onClick=()=>return toggleModal(),Details(props.row.id);
/>
</div>
</div>
)
thumbView = this.props.thumbView
componentDidUpdate(prevProps, prevState)
if (this.thumbView)
this.thumbView = false
let columns = [
name: "Name",
selector: "name",
sortable: true,
cell: row => (
<p title=row.name className="text-truncate text-bold-500 mb-0">
sessionStorage.Name
</p>
)
,
name: "Title",
selector: "title",
sortable: true,
cell: row => (
<p className="text-bold-500 text-truncate mb-0">row.title</p>
)
,
name: "Status",
selector: "status",
sortable: true,
cell: row => (
<Badge
color=row.status === null || row.status === '' ? "light-danger" : "light-success"
pill>
row.status === null || row.status === '' ? "Pending":"Active"
</Badge>
)
,
name: "Total Donation",
selector: "totaldonor",
sortable: true,
cell: row => (
<p className="text-bold-500 text-truncate mb-0">row.amounts</p>
)
,
name: "Start Date",
selector: "startdate",
sortable: true,
cell: row => <p className="text-bold-500 mb-0">row.startdate</p>
,
name: "Category",
selector: "category",
sortable: true,
cell: row => <p className="text-bold-500 mb-0">row.category</p>
,
name: "Actions",
sortable: true,
cell: row => (
<this.ActionsComponent
row=row
getData=this.props.getData
parsedFilter=this.props.parsedFilter
currentData=this.handleCurrentData
deleteRow=this.handleDelete
/>
)
]
this.setState( columns )
handleFilter = e =>
this.setState( value: e.target.value )
this.props.filterData(e.target.value)
handleRowsPerPage = value =>
let parsedFilter, getData = this.props
let page = parsedFilter.page !== undefined ? parsedFilter.page : 1
history.push(`/funding/?page=$page&perPage=$value`)
this.setState( rowsPerPage: value )
getData( page: parsedFilter.page, perPage: value )
handleSidebar = (boolean, addNew = false) =>
this.setState( sidebar: boolean )
if (addNew === true) this.setState( currentData: null, addNew: true )
handleDelete = row =>
this.props.deleteData(row)
this.props.getData(this.props.parsedFilter)
if (this.state.data.length - 1 === 0)
let urlPrefix = this.props.thumbView
? "/funding/"
: "/funding/"
history.push(
`$urlPrefixlist-view?page=$parseInt(
this.props.parsedFilter.page - 1
)&perPage=$this.props.parsedFilter.perPage`
)
this.props.getData(
page: this.props.parsedFilter.page - 1,
perPage: this.props.parsedFilter.perPage
)
handleCurrentData = obj =>
this.setState( currentData: obj )
this.handleSidebar(true)
handlePagination = page =>
let parsedFilter, getData = this.props
let perPage = parsedFilter.perPage !== undefined ? parsedFilter.perPage : 4
let urlPrefix = this.props.thumbView
? "/funding/b"
: "/funding/"
history.push(
`$urlPrefix?page=$page.selected + 1&perPage=$perPage`
)
getData( page: page.selected + 1, perPage: perPage )
this.setState( currentPage: page.selected )
render()
let
columns,
data,
allData,
totalPages,
value,
rowsPerPage,
currentData,
sidebar,
totalRecords,
sortIndex
= this.state
return (
<div
className=`data-list $
this.props.thumbView ? "thumb-view" : "list-view"
`>
<CustomHeader
handleSidebar=this.handleSidebar
handleFilter=this.handleFilter
handleRowsPerPage=this.handleRowsPerPage
rowsPerPage="5"
total=totalRecords
index=sortIndex
/>
<DataTable
columns=columns
data=data
pagination
noHeader
selectableRows
responsive
pointerOnHover
selectableRowsHighlight
onSelectedRowsChange=data =>
this.setState( selected: data.selectedRows )
customStyles=selectedStyle
subHeaderComponent=
<CustomHeader
handleSidebar=this.handleSidebar
handleFilter=this.handleFilter
handleRowsPerPage=this.handleRowsPerPage
rowsPerPage="5"
total=totalRecords
index=sortIndex
/>
sortIcon=<ChevronDown />
selectableRowsComponent=Checkbox
selectableRowsComponentProps=
color: "primary",
icon: <Check className="vx-icon" size=12 />,
label: "",
size: "sm"
/>
<Sidebar
show=sidebar
data=currentData
updateData=this.props.updateData
addData=this.props.addData
handleSidebar=this.handleSidebar
thumbView=this.props.thumbView
getData=this.props.getData
dataParams=this.props.parsedFilter
addNew=this.state.addNew
/>
<div
className=classnames("data-list-overlay",
show: sidebar
)
onClick=() => this.handleSidebar(false, true)
/>
</div>
)
const mapStateToProps = state =>
return
dataList: state.dataList
const handleSidebar = (boolean, addNew = false) =>
this.setState( sidebar: boolean )
if (addNew === true) this.setState( currentData: null, addNew: true )
export default connect(mapStateToProps,
getData,
deleteData,
updateData,
addData,
getInitialData,
filterData
)(DataListConfig)
出于安全目的,我删除了我的 api 端点
bug image
【问题讨论】:
【参考方案1】:DataListConfig
组件尝试渲染<this.ActionsComponent>
。因为ActionsComponent
是在componentDidMount
方法内部定义的,而不是在类级别,所以this.ActionsComponent
是未定义的。导致错误的原因。
尽管在另一个组件中定义一个组件是一个坏主意。在类组件的类中作为字段,这将意味着该类组件的每个实例will have their own version of the function component。这充其量闻起来很腥,而且不是很像 React。
将ActionsComponent
完全移出DataListConfig
组件,并通过其道具传递所需的数据。
function ActionsComponent(props)
// ...
class DataListConfig extends React.Component
// ...
【讨论】:
如何在函数内部设置状态,可以吗? @silexsecurelab 您传递了一个回调函数,该函数通过 props 将父组件中的状态设置给组件。有关示例,请参见React tutorial(尤其是它们将onClick
传递给<Square>
的部分)以上是关于错误:元素类型无效:在尝试更新状态时,应在反应中出现字符串的主要内容,如果未能解决你的问题,请参考以下文章
反应本机错误!元素类型无效:应为字符串或类/函数,但得到:未定义
使用多个(最新)第 3 方反应库反应“未捕获的不变违规:元素类型无效”
在反序列化过程中出现下一个异常:“源数据中的无效字段:0”。如何找出源代码中的原因/错误位置?