首页 > 解决方案 > 如何使用函数组件根据另一个列表将新属性添加到 JSON 列表中

问题描述

有点 JavaScript/react 新手。

目前在基本的 react/JavaScript 语法上有点卡住,这就是我想要实现的目标:

import axios from 'axios';
import React, { useState, useEffect, useMemo } from "react";

const testCombineApi = () => {
    const [assocs, setAssocs] = useState([])
    const [loadingData, setLoadingData] = useState([])
    const [corenodes, setCoreNodes] = useState([])

    const projectId = 1
    
    /// i can probably combine both calls? with another then?
    useEffect(() => {
        async function getData() {
            await axios
            .get(`/api/.../`)
            .then((response) => {
                console.log(response.data);
                setCoreNodes(response.data)
                setLoadingData(false);
            });
        }
        if (loadingData) {
            getData();
        }
        }, []);

    useEffect(() => {
    async function getData() {
        await axios
        .get(`/api/.../${projectId}/`)
        .then((response) => {
            console.log(response.data);
            setAssocs(response.data)
            setLoadingData(false);
        });
    }
    if (loadingData) {
        getData();
    }
    }, []);

    // Trying to add the property "withproject" to every json in the list corenodes
    const initnodes = setCoreNodes({
        ...corenodes, 
        withproject: false
    })

    //this is the part i just to combine the two pieces of info
    // i usually use python, so what i want to do would be 
    // for node in nodes:
    //     node.withproject = True

    // for assoc in assocs:
    //     targetId = assoc.id
    //     for node in nodes:
    //         if targetId = node.id:
    //             node.withproject = False
  
    const testing123 = assocs =>  {
        initnodes
        for (let i=0; i < assocs.length; i++) {
            let id = assocs[i].id
            for (let j = 0; j < corenodes.length; j++) {
                let nodeId = corenodes[j].id  
                {id == nodeId &&
                 setCoreNodes({...corenodes, [corenodes[j].withproject]: false})   
                }
            }

        }
        console.log(corenodes)
    }

    return(
        <ul> {testing123(assocs)} </ul>
    )
    }
    export default testCombineApi

关于我想要实现的目标,我已将我的代码作为 python 包含在评论中。但为了便于阅读,我也会把它放在这里

for node in nodes:
    node.withproject = True

for assoc in assocs:
    targetId = assoc.id
    for node in nodes:
        if targetId = node.id:
            node.withproject = False

我正在尝试添加一个额外的列,该列最终将呈现为表中的复选框,然后我可以使用它然后通过 API 更新我的数据库

这是节点 JSON 的样子

[
    {
        "id": 263,
        "hostname": "qwer123",
        "serial": "",
    },
    {
        "id": 264,
        "hostname": "asdf123",
        "serial": "",
    },
]

当我使用特定的 {$projectID} 查询 API 时,我得到的基本相同

这是一个合理的反应吗?或者我必须重新调整我想让它工作的方式?

提前致谢!

标签: javascriptreactjs

解决方案


好吧,让我们稍微改变一下视角!“response.data”不是 JSON,它是 JS 对象的集合(列表)。在 JS 中,您有一个循环遍历整个集合的函数,允许您使用箭头函数来转换对象。

在你的情况下:

const initnodes = setCoreNodes({
        ...corenodes, 
        withproject: false
    })

可以改为:

const coreNodeModels = corenodes
.map(coreNode => {
    
    // this will create a new object 
    return { 
       withProject: false,
       ...coreNode // this will copy all properties from the coreNode object
    }
})

在此之后,您将拥有与 coreNode 不同类型的 coreNodeModel 集合,因此将它们存储在不同的“useState”状态中。

希望对我有所帮助,还可以查看 typescript,起初它更容易理解,并且不会让您将类型相互混淆。

干杯!


推荐阅读