【问题标题】:How to map over an object which has a unique id for each object values and return the values to a React component如何映射具有每个对象值的唯一 id 的对象并将值返回给 React 组件
【发布时间】:2017-12-18 01:02:13
【问题描述】:

我正在开发一个 redux 项目,我想在其中检索存储在 API 服务器中的值。我想将来自 API 的数据存储在我的 redux 存储中,然后检索这些值并将其显示在我的反应组件中。数据在 API 服务器中是对象的形式,但每个值都有一个唯一的 id。所以,在我的例子中,数据是一个帖子列表。所以,每个帖子都有一个唯一的 id,并具有所有其他详细信息,如时间戳,post-title,post-author 等。这是来自 API 的帖子默认数据的样子:

const defaultData = {
  "8xf0y6ziyjabvozdd253nd": {
    id: '8xf0y6ziyjabvozdd253nd',
    timestamp: 1467166872634,
    title: 'Udacity is the best place to learn React',
    body: 'Everyone says so after all.',
    author: 'thingtwo',
    category: 'react',
    voteScore: 6,
    deleted: false,
    commentCount: 2
  },
  "6ni6ok3ym7mf1p33lnez": {
    id: '6ni6ok3ym7mf1p33lnez',
    timestamp: 1468479767190,
    title: 'Learn Redux in 10 minutes!',
    body: 'Just kidding. It takes more than 10 minutes to learn technology.',
    author: 'thingone',
    category: 'redux',
    voteScore: -5,
    deleted: false,
    commentCount: 0
  }
}

注意:这里的“id”是一个随机数(如“8xf0y6ziyjabvozdd253nd”)变成一个整数,即第一个帖子的id为1,第二个为2。

因此,我可以将来自帖子 API 的数据存储在我的 redux“存储”中。我将帖子对象转换为一个数组(因为我们无法映射到一个对象),因为我想映射到这个数组并在我的 React 组件中显示数据。但是,我无法在我的组件,可能是因为它在数组中的每个对象之前都有一个 id。这就是我尝试映射数组的方式,我没有收到任何错误,但我没有看到组件中对象的结果。我的组件文件看起来像这样:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { fetchPosts } from '../actions';
import _ from 'lodash';

class PostsIndex extends Component {
  componentDidMount() {
    this.props.dispatch(fetchPosts())
    .then(() => {
      this.setState({
        loading : false
      });
    //  console.log(this.props.posts.posts[0])
    })
  }

  render() {
//  console.log(this.props.posts.posts)   
  const obj = this.props.posts.posts;
  let arr;
  if (obj) {
     arr = Object.values(obj); //Converting an Object into an array
  }
  console.log(arr);         //returns the converted array from an object

    return(
      <div>
              {
                arr               ?
                <div>
                { arr.map(post =>
                   {
                      <div>
                          {post.title}
                      </div>
                    })
                  }
                </div>
                                  :
                <div>
                  No Data
                </div>
              }
      </div>
    );
  }
}

function mapStateToProps(state) {
  return { posts: state.posts };
}

export default connect(mapStateToProps)(PostsIndex);

当我 console.log 我的状态时,转换后的数组如下所示:

展开后的样子:

我想从上面的数组中检索几乎所有的值。谁能告诉我如何从数组中获取数据并映射到数组以显示我的 React 组件中的值?

【问题讨论】:

  • 你会爱上console.table(...)

标签: javascript arrays reactjs redux


【解决方案1】:

您可以将数据保留为对象,并使用Object.keys 获取键数组,映射键,并使用键访问嵌套对象。如果您不知道数据源的形状,可以使用递归。

这是一个有效的code sandbox example,我在其中获取了您的数据源并将其转换为表格来说明如何执行此操作。

代码如下:

import React from 'react';
import { render } from 'react-dom';
import Hello from './Hello';


const defaultData = {
  "8xf0y6ziyjabvozdd253nd": {
    id: '8xf0y6ziyjabvozdd253nd',
    timestamp: 1467166872634,
    title: 'Udacity is the best place to learn React',
    body: 'Everyone says so after all.',
    author: 'thingtwo',
    category: 'react',
    voteScore: 6,
    deleted: false,
    commentCount: 2
  },
  "6ni6ok3ym7mf1p33lnez": {
    id: '6ni6ok3ym7mf1p33lnez',
    timestamp: 1468479767190,
    title: 'Learn Redux in 10 minutes!',
    body: 'Just kidding. It takes more than 10 minutes to learn technology.',
    author: 'thingone',
    category: 'redux',
    voteScore: -5,
    deleted: false,
    commentCount: 0
  }
}

const TableHeader = ({ fields }) => (
  <thead>
    <tr>
    {
      fields.map( field => <th key={ field }>{ field }</th>)
    }
    </tr>
  </thead>
);

const TableBody = ({ data }) => (
  <tbody>
    {
      Object.keys(data).map(
        datum =>
          <tr>
          {
            Object.keys(data[datum]).map(
              field => <td>{data[datum][field]}</td>
            )
          }
          </tr>
      )
    }
  </tbody>
);

const App = () => (
  <table>
    <TableHeader fields={ Object.keys(defaultData[Object.keys(defaultData)[0]]) } />
    <TableBody data={defaultData} />
  </table>
);

render(<App />, document.getElementById('root'));

【讨论】:

  • 非常感谢您的帮助。一定会尝试一下 :)
【解决方案2】:

您需要映射您的数据。像这样的:

<div>
  <ul>
  {props.incomingDataArray.map((singleArrayItem, index) => {
    return (
    <li key="list + index">{singleArrayItem.commentCount}</li>
    <li key="list + index">{singleArrayItem.timestamp}</li>
    )
   })
  }
  </ul>
<div>

【讨论】:

  • 别忘了在返回的组件中添加key(你也可以抽象掉)
  • 我不确定您的回答是否对 OP 有所帮助。
  • 感谢您的帮助。让我试一试。稍后会更新你们
  • 使用 ReactJS 你不能返回两个兄弟组件。您需要将两个
  • 包装在
      中。关键属性只需一次。不过,最好的办法是创建一个哑组件。
【解决方案3】:

您在地图中忘记了return

  render() {   
   const obj = this.props.posts.posts;
   let arr;
   if (obj) {
     arr = Object.values(obj); //Converting an Object into an array
   }

   return (
    <div>
      { arr ?
        <div>
          { arr.map(post => {
              return (
                <div key={post.id}>
                  {post.title}
                </div>
              )
            })
          }
        </div> :
        <div>
          No Data
        </div>
       }
      </div>
    );
  }

或者,或者,使用单线删除花括号:

arr.map(post => (<div key={post.id}>
                   {post.title}
                 </div>
                )
       )

不要忘记key 属性。
我还建议你抽象出你的愚蠢组件。它会让你的代码更具可读性。

【讨论】:

    猜你喜欢
    相关资源
    最近更新 更多
    热门标签