繁体   English   中英

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

[英]Uncaught TypeError: Cannot add property 0, object is not extensible at Array.push

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

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

 const temp = Object.freeze([]); temp.push(42);

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

如果要更改这些内容,则需要将temp存储在 state 中并在添加后重新渲染; 请参阅***评论(我还将temp重命名为dataGridRows ):

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

感谢 TJ Crowder 的回答,它帮助我理解了真正的问题不是你要传递值的 object,而是原来的 object,因为它是通过引用传递的。

所以,当你有错误时

object is not extensible at array

解决方案是将原始 object 的值复制到目标,而不仅仅是用等号 (=) 运算符赋值。

例如

targetObject.nodes.map( (newNode: any) => {

    //here I create a new object and enrich it with an array and a boolean
    let newFullNode = Object.assign({}, newNode, {nodes: []  , hasChildren:true}); 
    
    targetObject.nodes.push(newFullNode);
});

我稍后更新了 targetObject,当我更新它时,才收到错误,这误导了我。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM