未捕获的类型错误:无法添加属性 0,对象在 Array.push 中不可扩展

Ibr*_*nku 6 javascript firebase reactjs firebase-realtime-database

从 firebase 获取数据并将数据推送到数组中时出现此错误。在这里,我定义了一个临时数组,当我将 firebase onValue 内的数据推送到此临时数组时,我收到此错误 Uncaught TypeError: Cannot add property 0, object is not extensible at Array.push。这是我的代码

function Room() {
const [textInput, setTextInput] = useState('');
const temp = [];

const handleTextInputChange = (event) => {
    setTextInput(event.target.value);
};

const handleSubmit = () => {
    console.log('here goes');
    if (textInput !== '') {
        const refer = ref(database, 'rooms/');
        push(refer, textInput).then(() => {
            setTextInput('');
            toast.success('Added Successfully!');
        });
    }
};

useEffect(() => {
    const refer = ref(database, 'rooms/');
    onValue(refer, (snap) => {
        snap.forEach((child) => {
            console.log(child.val() + child.key);
            // I am getting error in this line
            temp.push({ id: child.key, firstName: child.val() });
        });
    });
}, []);

return (
  <div>
    <Grid item xs={12}>
                <SubCard title="Room List">
                    <div style={{ height: 400, width: '100%' }}>
                        <DataGrid
                            rows={temp}
                            columns={columns}
                            pageSize={5}
                            rowsPerPageOptions={[5]}
                            components={{
                                Toolbar: CustomToolbar
                            }}
                        />
                    </div>
                </SubCard>
            </Grid>
  </div>
)
Run Code Online (Sandbox Code Playgroud)

T.J*_*der 10

当您尝试推送到冻结数组时,您遇到的错误是:

const temp = Object.freeze([]);
temp.push(42);
Run Code Online (Sandbox Code Playgroud)

您已经表明您正在将数组传递给DataGridas rows。显然,DataGrid冻结数组,大概是因为它需要知道它的内容不会改变。

如果你想改变这些内容,你需要存储temp在状态中并在添加后重新渲染;查看***评论(我也已重命名tempdataGridRows):

function Room() {
    const [textInput, setTextInput] = useState('');
    // *** Store it in state
    const [dataGridRows, setDataGridRows] = useState([]);

    const handleTextInputChange = (event) => {
        setTextInput(event.target.value);
    };

    const handleSubmit = () => {
        console.log('here goes');
        if (textInput !== '') {
            const refer = ref(database, 'rooms/');
            push(refer, textInput).then(() => {
                setTextInput('');
                toast.success('Added Successfully!');
            });
        }
    };

    useEffect(() => {
        const refer = ref(database, 'rooms/');
        onValue(refer, (snap) => {
            snap.forEach((child) => {
                console.log(child.val() + child.key);
                // *** Add to it in state; this will cause a re-render
                // so DataGrid picks up the change
                setDataGridRows(dataGridRows => [...dataGridRows, { id: child.key, firstName: child.val() }];
            });
        });
    }, []);

    return (
        <div>
            <Grid item xs={12}>
                <SubCard title="Room List">
                    <div style={{ height: 400, width: '100%' }}>
                        <DataGrid
                            rows={dataGridRows}
                            columns={columns}
                            pageSize={5}
                            rowsPerPageOptions={[5]}
                            components={{
                                Toolbar: CustomToolbar
                            }}
                        />
                    </div>
                </SubCard>
            </Grid>
        </div>
    )
}
Run Code Online (Sandbox Code Playgroud)