React Hooks:未捕获的类型错误:setData({...}) 不是函数

时间:2021-06-02 16:44:00

标签: javascript reactjs react-hooks

所以我对 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!

1 个答案:

答案 0 :(得分:0)

好的,经过反复试验后,我注意到在 setData({...}) 末尾有一个分号是必须的。如果您查看我的 RowClick 方法,您会注意到我将下一行括在括号中,并且 react 正在阅读该行:

setData({...data, updateClickedDispatchersRow: id, SubData: dispatcher_info, ModalOpen: true})(document.getElementById('myModal')).style.display = "block";

而不是将其作为两条单独的行阅读。因此,通过在 setData 末尾添加分号或在下一行去掉不必要的括号,错误就会消失。

不确定这是错误还是设置为这种方式,但我确实觉得它有点奇怪。