解析的JSON数据上的嵌套映射函数

时间:2018-01-28 12:14:00

标签: javascript json react-native

我从数据库接收JSON数据  [{"table_cols":["id","stud_name","stud_school"]}]

 console.log("Response is: " + resp._bodyText); {/*Response is: [{"table_cols":["id","stud_name","stud_school"]}]*/}

         let parsedData = JSON.parse(resp._bodyText);
         console.log(parsedData) //Object
        this.setState({...this.state,cols_of_sel_tab:parsedData})


        for(let i=0; i<this.state.cols_of_sel_tab.length;i++)
        {
            cols = [];
            console.log(this.state.cols_of_sel_tab[i])
            let cols = this.state.cols_of_sel_tab[i]
            console.log("WOW")
            for (let j = 0; j<cols.length; j++){
                console.log(cols[j])
            }
        }

输出:{table_cols:Array(3)} WOW

预期:迭代内部for循环 所需的输出是:id,stud_name,stud_school

尝试:使用forEach而不是inner for循环 错误:... \ node_modules \ react-native \ Libraries \ ReactNative \ YellowBox.js:82可能的未处理承诺拒绝(id:0): TypeError:无法读取属性&#39; forEach&#39;未定义的 TypeError:无法读取属性&#39; forEach&#39;未定义的

我需要帮助!

3 个答案:

答案 0 :(得分:1)

状态更新are asynchronous。如果您想循环浏览当时收到的数据,请使用parsedData,而不是this.state.cols_of_sel_tab

另外,永远不要这样做:

this.setState({...this.state,cols_of_sel_tab:parsedData});

如果您根据当前状态设置状态,则不得传入对象;相反,您必须传入一个回调函数,该函数使用它接收的状态作为参数(有关详细信息,请参阅链接的文档)。

但是在这种情况下,你根本不需要...this.state,所以如果你这样做就没问题了:

this.setState({cols_of_sel_tab:parsedData});

...然后(再次)循环播放parsedData而非this.state.cols_of_sel-tab

另外,cols存在问题:您在使用let声明之前尝试在块中使用它。如果您确实运行了该代码,那么它将失败并显示错误,指出cols未定义(因为您无法访问块中letconst声明的标识符在声明之前,即使它存在于外部范围内)。

答案 1 :(得分:1)

<强> 1。解决您的问题

为什么你(以某种方式没有语法错误而没有得到空状态问题)的主要问题得到

输出:{table_cols:Array(3)} WOW

而不是数组项,因为您的回复模型

[
  {"table_cols":
      ["id",
      "stud_name",
      "stud_school"]
  }
]

所以,而不是

let cols = this.state.cols_of_sel_tab[i]

应该是

let cols = this.state.cols_of_sel_tab[i].table_cols

输入将是: {table_cols:Array(3)} 哇 ID stud_name stud_school

<强> 2。语法错误

cols = [];
let cols = this.state.cols_of_sel_tab[i]

您正在尝试将空数组分配给未定义的变量。 在这个特定的例子中,你可以修改第一行

第3。处理状态

在您的代码示例中,您有两个目标:使用新数据更新状态并使用新数据进行输出。因为状态更新是异步的,操作和输出你已经拥有的数据更加安全(我修改了调试控制台输出)。

this.setState({cols_of_sel_tab: parsedData})
for(let i=0; i<parsedData.length; i++) {
    let cols = parsedData.cols_of_sel_tab[i].table_cols
    for (let j = 0; j<cols.length; j++) {
        console.log(cols[j])
    }
}

另外,导致states updates are merged你可以修改this.state的扩展运算符,就像上面的代码一样。

4.更多改进

  1. 在问题的标题中提到了地图功能,您可以使用它。

    parsedData.map(
        col_of_sel => col_of_sel.table_cols.map(
            cols => console.log(cols)
        )
    )
    

    或者,如果您只需要第一个对象的table_cols:

    parsedData[0].table_cols.map(cols => console.log(cols))
    
  2. 您所讨论的示例中有不同的代码样式:分号存在,缩进的差异。我建议使用某种prettier来完善代码,以便更容易阅读。

  3. <强>最后

    let parsedData = JSON.parse(resp._bodyText)
    this.setState({ cols_of_sel_tab: parsedData })
    parsedData[0].table_cols.map(cols => console.log(cols))
    

答案 2 :(得分:0)

问题是对JSON数据代表的内容略有误解。

如果我们让JSON更漂亮一点:

[
    {"table_cols":
        ["id",
        "stud_name",
        "stud_school"]
    }
]

外方括号代表array。此array包含索引为0的一个项目,即table_cols个对象。此对象还包含array,其中包含表格字段。

您在外部阵列上运行for循环。此循环将遇到的第一项是索引0处的对象。要访问表格列,您需要在table_cols上运行第二个for循环,或在this.state.cols_of_sel_tab[0].table_cols上运行原始循环。