所以我对 React Hooks 相当陌生,但我确实对它们的工作方式有很好的了解,或者至少我认为我做到了。在我的组件中,我试图以与 useState
类似的方式使用 setState
,但在尝试调用我的钩子方法 setData
时遇到此错误:Uncaught TypeError: setData({...}) is not a function
< /p>
我的组件如下所示:
import React, { useState, useEffect} from 'react';
import DispatcherModal from './DispatcherModal.js';
import Spinner from '../../components/Spinner';
//Formats the DispatcherTable Information for each row
const DispatcherTable = (props) => {
const [data, setData] = useState({
updateClickedDispatchersRow: "",
filterArray: "",
User: null,
DispatchersDB: [],
Loading: true,
ModalOpen: false,
SubData: null,
})
useEffect(() => {
let mounted = true;
let username = localStorage.getItem('user');
socket.emit('getUserByUsername', username, (user) => {
if(!user){
console.error('There was an issue validating user information.')
}else{
socket.emit('selectFromDispatchersForTM', (result) => {
if(mounted){
setData({...data, User: user[0], DispatchersDB: result, Loading: false})
}
});
}
})
return () => {
mounted = false;
}
},[])
const RefreshTableData = () => {
socket.emit('selectFromDispatchersForTM', (result) => {
setData({...data, DispatchersDB: result})
});
}
const onChange = (e) => {
setData({...data, filterArray: e.target.value.toLowerCase()})
}
const AddNewItemBtn = () => {
if (data.User.UserType == 'admin') {
setData({...data, updateClickedDispatchersRow: "", ModalOpen: true})
(document.getElementById('myModal')).style.display = "block";
(document.getElementById('modal_dispatchers')).style.display = "block";
}
}
const RowClick = (e) => {
let id = e.target.id.replace(e.target.id.substring(0, 4), '')
let dispatcher_info = data.DispatchersDB.filter(e => e.UserID == id)[0]
setData({...data, updateClickedDispatchersRow: id, SubData: dispatcher_info, ModalOpen: true})
(document.getElementById('myModal')).style.display = "block";
(document.getElementById('modal_dispatchers')).style.display = "block";
}
function RenderBody() {
let dispatchersDB = (data.DispatchersDB).filter(obj => ((obj.Activity + " " + obj.Email + " " + obj.FullName + " " + obj.FirstName + " " + obj.LastName + " " + obj.PhoneNumber + " " + obj.UserType + " " + obj.Username + " " + obj.UserID).toLowerCase()).includes(data.filterArray));
let rows = [];
for (let i = 0; i < dispatchersDB.length; i++) {
rows.push(
<tr className="TableBodyRow" id={"DISP" + dispatchersDB[i].UserID} onClick={RowClick} key={i}>
<td className="tableData20" id={"DISP" + dispatchersDB[i].UserID} onClick={RowClick}>
{dispatchersDB[i].Username}
</td>
<td className="tableData20" id={"DISP" + dispatchersDB[i].UserID} onClick={RowClick}>
{dispatchersDB[i].UserType}
</td>
<td className="tableData20" id={"DISP" + dispatchersDB[i].UserID} onClick={RowClick}>
{dispatchersDB[i].FirstName} {dispatchersDB[i].LastName}
</td>
<td className="tableData20" id={"DISP" + dispatchersDB[i].UserID} onClick={RowClick}>
{dispatchersDB[i].PhoneNumber}
</td>
<td className="tableData20" id={"DISP" + dispatchersDB[i].UserID} onClick={RowClick}>
{dispatchersDB[i].Email}
</td>
</tr>
);
}
return (
<div className="TableBodyScrollingDiv">
<table className="TableBodyContainer">
<tbody>
{rows}
</tbody>
</table>
</div>
);
}
function RenderMainBody(){
let divtorender = null;
if(data.Loading){
divtorender = (
<div style={{marginTop: '25%'}}>
<Spinner></Spinner>
</div>
)
}else {
divtorender = (
<div style={{height: '100%'}}>
<div className="TitleBarContainer">
<h1 >Dispatchers Table</h1>
</div>
<div className="TopBarContainer">
<input type="text" className="TopBarSearchInput" placeholder="Search.." title="" onChange={onChange} />
</div>
<table className="TableHeaderContainer" style={{width: '100%'}}>
<thead>
<tr>
<th className="tableData20" id="TITL">Username</th>
<th className="tableData20" id="TITL">UserType</th>
<th className="tableData20" id="TITL">Name</th>
<th className="tableData20" id="TITL">Number</th>
<th className="tableData20" id="TITL">Email</th>
</tr>
</thead>
</table>
{RenderBody()}
<div className="BottomBarContainer" id="AddDispatcherContainer">
{data.User.UserType == 'admin' ? <span><button className="RTIButton" id="AddNewItemBtn" onClick={AddNewItemBtn} style={{ float: 'right' }}>Add</button></span> : undefined}
</div>
</div>
)
}
return divtorender;
}
return(
<div className="ViewedContentContainer" id="OpenContainer" >
{RenderMainBody()}
</div>
)
}
export default DispatcherTable;
当我尝试使用方法 RowClick
以及添加按钮时出现问题。奇怪的是,当我在 setData
中调用 useEffect
时,我没有收到此错误。只有在组件安装后。我尝试将 RenderBody 方法更改为箭头函数,但这也不起作用。这是一个在谷歌上查找的广泛问题,所以我很难找到任何有同样问题的人。
如果有人有任何建议,或者可以看到我做错了什么,那将非常有帮助。 TIA!
答案 0 :(得分:0)
好的,经过反复试验后,我注意到在 setData({...})
末尾有一个分号是必须的。如果您查看我的 RowClick
方法,您会注意到我将下一行括在括号中,并且 react 正在阅读该行:
setData({...data, updateClickedDispatchersRow: id, SubData: dispatcher_info, ModalOpen: true})(document.getElementById('myModal')).style.display = "block";
而不是将其作为两条单独的行阅读。因此,通过在 setData
末尾添加分号或在下一行去掉不必要的括号,错误就会消失。
不确定这是错误还是设置为这种方式,但我确实觉得它有点奇怪。