【问题标题】:how to map an array of objects of array of objects with React如何使用 React 映射对象数组的对象数组
【发布时间】:2019-09-23 14:36:10
【问题描述】:

console.log(notes)时有这个json格式:

{
  "document_tone": {
    "tone_categories": [
      {
        "tones": [
          {
            "score": 0.027962,
            "tone_id": "anger",
            "tone_name": "Colère"
          },
          {
            "score": 0.114214,
            "tone_id": "sadness",
            "tone_name": "Tristesse"
          }
        ],
        "category_id": "emotion_tone",
        "category_name": "Ton émotionnel"
      },
      {
        "tones": [
          {
            "score": 0.028517,
            "tone_id": "analytical",
            "tone_name": "Analytique"
          },
          {
            "score": 0,
            "tone_id": "tentative",
            "tone_name": "Hésitant"
          }
        ],
        "category_id": "language_tone",
        "category_name": "Ton de langage"
      },
      {
        "tones": [
          {
            "score": 0.289319,
            "tone_id": "openness_big5",
            "tone_name": "Ouverture"
          },
          {
            "score": 0.410613,
            "tone_id": "conscientiousness_big5",
            "tone_name": "Tempérament consciencieux"
          },
          {
            "score": 0.956493,
            "tone_id": "emotional_range_big5",
            "tone_name": "Portée émotionnelle"
          }
        ],
        "category_id": "social_tone",
        "category_name": "Ton social"
      }
    ]
  },
  "idMedia": 25840
}

这是 console.log(notes) 的图片,我不知道为什么除了预期的结果之外我得到一个空数组

但是当我尝试映射 tone_categories 时,我得到了这个错误:

TypeError: Cannot read property 'map' of undefined

这是我目前构建的代码:

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      notes: [],
    };
  }

componentWillMount() {
  fetch('http://localhost:3000/api/users/analyzeMP3?access_token=GVsKNHWnGWmSZmYQhUD03FhTJ5v80BjnP1RUklbR3pbwEnIZyaq9LmZaF2moFbI6', { 
    method: 'post', 
    headers: new Headers({
      'Authorization': 'Bearer', 
      'Content-Type': 'application/x-www-form-urlencoded'
    }), 
  })
    .then(response => response.text())
    .then(JSON.parse)
    .then(notes => this.setState({ notes }));
}

render() {
  const { notes } = this.state;
  console.log('notes',notes)

  return (

    <div className="App">
     {notes !== undefined && notes !== "" &&  notes !== [] ? notes.document_tone.map((tone_categories, idx) => {
    {console.log('notes',notes.document_tone[tone_categories].category_name)}
     }) : null}  

      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

}

export default App;

【问题讨论】:

  • 使用 componentDidMount 代替 componentWillMount
  • componentWillMount() 已弃用,请改用componentDidMount() 并确保您的render() 函数检查notes 是否为undefined。顺便说一句,notes !== [] 永远是true

标签: javascript arrays json reactjs object


【解决方案1】:

您的初始状态是notes: [],因此在第一次渲染期间该数组将为空,如果您尝试从一个空数组访问一个项目,则会收到错误消息。

在这种情况下,更好的方法是设置加载状态并延迟渲染,直到您获取数据:

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      notes: [],
      loading: true // Set the loading to true initially
    };
  }

  componentDidMount() {
    fetch(
      "http://localhost:3000/api/users/analyzeMP3?access_token=GVsKNHWnGWmSZmYQhUD03FhTJ5v80BjnP1RUklbR3pbwEnIZyaq9LmZaF2moFbI6",
      {
        method: "post",
        headers: new Headers({
          Authorization: "Bearer",
          "Content-Type": "application/x-www-form-urlencoded"
        })
      }
    )
      .then(response => response.text())
      .then(JSON.parse)
      .then(notes => this.setState({ notes, loading: false })); // reset the loading when data is ready
  }

  render() {
    const { notes, loading } = this.state;
    console.log("notes", notes);

    return loading ? (
      <p>Loading...</p> // Render the loader if data isn't ready yet
    ) : (
      <div className="App">//...</div>
    );
  }
}

【讨论】:

    【解决方案2】:

    问题在于这个条件notes !== [] 总是返回真。如果需要检查数组是否为空,可以使用array.length === 0。还要使用 componentDidMount 而不是 componentWillMount,因为 componentWillMount 已被弃用。

    你可以这样做

    return (
        <div className="App">
          {
            notes && notes.length > 0 ? 
            notes.document_tone.map((tone_categories, idx) => {
                return notes.document_tone[tone_categories].category_name;
            }) : null
          }
        </div>
      );
    

    【讨论】:

      【解决方案3】:

      那是因为最初notes 是一个空数组并且没有document_tone 键。所以这一行会抛出错误notes.document_tone.map

      添加一个条件并检查notes是否有document_tone

      <div className="App">
           {
      notes !== undefined && notes !== "" &&  notes !== [] && notes.document_tone.length >0 ?
      notes.document_tone.map((tone_categories, idx) => {
          {console.log('notes',notes.document_tone[tone_categories].category_name)}
           }) :
           null}  
      

      【讨论】:

        【解决方案4】:

        当您启动应用程序时,构造函数会运行,您使用 notes=[] 设置状态,会发生 render() 并将其打印在控制台中。

        然后,在 willComponentMount() 之后,notes 有了一个新的值,并触发了一个新的 render()。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-06-23
          • 2017-04-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-06-17
          • 2021-12-04
          • 1970-01-01
          相关资源
          最近更新 更多