我如何在React中循环遍历JSON对象

时间:2019-09-23 12:36:01

标签: javascript json reactjs

我正在尝试从以下JSON对象 data.json中检索信息:

{
  "status": "ok",
  "feed": {
    "title": "NOS Nieuws",
  },
  "items": [
    {
      "title": "Test Title",
      "description": "Test description",
      "enclosure": {
        "link": "https://examplelink.com/1008x567.jpg",
        "type": "image/jpeg"
      },
      "categories": []
    },
    {
      "title": "Test Title 2",
      "description": "Test 2",
      "enclosure": {
        "link":  "link": "https://examplelink.com/1008x567.jpg",
        "type": "image/jpeg"
      },
      "categories": []
    }
  ]
}

因此,我想遍历此JSON对象以显示所有可用项及其相应的标题,描述和附件链接。

我知道我可以通过以下方式分别访问它们:

const items = data.items;
const title = items.title;
const url = items.enclosure.link;

通常,我会进行for循环并遍历data.items [i]。但是,由于这是一个React对象,而不是数组,因此它的工作方式有所不同。

我当前的代码:

class Feed extends Component {
  render() {
    const items = data.items[0];
    const title = items.title;
    const url = items.enclosure.link;
    const description = items.description;
    const feed = [
      {
        url: url,
        title: title,
        description: description
      }
    ];

    return (
      <div className="feed">
        <h1>Newsfeed</h1>
        <div className="columns is-multiline">
          {feed.map(article => (
            <div className="column is-one-third">
              <NewsCard
                article={article}
                title={items.title}
                description={items.description}
              />
            </div>
          ))}
        </div>
      </div>
    );
  }
}

现在它仅显示对象的第一个条目(因为它具有const items = data.items [0])如何遍历data.json并在NewsCard组件中显示其内容?我知道每个孩子都应该有一个独特的“钥匙”道具,但这就是我被困住的地方。

3 个答案:

答案 0 :(得分:1)

  

我想遍历此JSON对象以显示所有可用的   项目及其相应的标题描述附件链接

然后不要这样做:

const items = data.items[0];

尝试一下:

const items = data.items;

然后,您可以使用map函数,如下所示:

items.map(item => (
  <div className="column is-one-third">
    <NewsCard
      article={item.enclosure.link}
      title={item.title}
      description={item.description}
    />
  </div>
));

答案 1 :(得分:0)

class ResizablePixmap(QLabel):
    def __init__(self, bytes_image):
        QLabel.__init__(self)
        self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
        self.setAlignment(Qt.AlignCenter)
        self.setStyleSheet("background-color: #ffffff;")

        self.update_pixmap(bytes_image)

    def update_pixmap(self, bytes_image):
        self.bytes_image_edit = bytes_image
        self.current_pixmap = self._bytes2pixmap(bytes_image)

    def scale(self, fromResize=False):
        # use a single central method for scaling; there's no need to call it upon
        # creation and also resize() won't work anyway in a layout
        self.setPixmap(self.current_pixmap.scaled(self.width(), self.height(), 
            Qt.KeepAspectRatio, Qt.SmoothTransformation))

    def resizeEvent(self, event):
        super(ResizablePixmap, self).resizeEvent(event)
        self.scale(True)

    @staticmethod
    def _bytes2pixmap(raw_image):
        image = QImage()
        image.loadFromData(raw_image)
        return QPixmap(image)


class SelectablePixmap(ResizablePixmap):
    selectionActive = pyqtSignal(bool)

    def __init__(self, bytes_image):
        super().__init__(bytes_image)

        # activate mouse tracking to change cursor on rubberband hover
        self.setMouseTracking(True)
        self.currentQRubberBand = None
        self.rubber_band_offset = None
        self.moveDirection = 0

    def create_selection(self, pos):
        if self.currentQRubberBand:
            self.cancel_selection()
        self.currentQRubberBand = QRubberBand(QRubberBand.Rectangle, self)
        self.currentQRubberBand.setStyle(QStyleFactory.create("Fusion"))
        self.currentQRubberBand.setGeometry(pos.x(), pos.y(), 1, 1)
        self.currentQRubberBand.show()
        self.originQPoint = pos
        self.currentQRubberBand.installEventFilter(self)

    def cancel_selection(self):
        self.currentQRubberBand.hide()
        self.currentQRubberBand.deleteLater()
        self.currentQRubberBand = None
        self.originQPoint = None
        self.selectionActive.emit(False)

    def scale(self, fromResize=False):
        if fromResize and self.currentQRubberBand:
            # keep data for rubber resizing, before scaling
            oldPixmapRect = self.pixmap().rect()
            oldOrigin = self.currentQRubberBand.pos() - self.pixmapRect.topLeft()
        super(SelectablePixmap, self).scale()

        # assuming that you always align the image in the center, get the current
        # pixmap rect and move the rectangle center to the current geometry
        self.pixmapRect = self.pixmap().rect()
        self.pixmapRect.moveCenter(self.rect().center())
        if fromResize and self.currentQRubberBand:
            # find the new size ratio based on the previous
            xRatio = self.pixmapRect.width() / oldPixmapRect.width()
            yRatio = self.pixmapRect.height() / oldPixmapRect.height()
            # create a new geometry using 0-rounding for improved accuracy
            self.currentQRubberBand.setGeometry(
                round(oldOrigin.x() * xRatio, 0) + self.pixmapRect.x(), 
                round(oldOrigin.y() * yRatio + self.pixmapRect.y(), 0), 
                round(self.currentQRubberBand.width() * xRatio, 0), 
                round(self.currentQRubberBand.height() * yRatio, 0))

    def updateMargins(self):
        # whenever the rubber rectangle geometry changes, create virtual
        # rectangles for corners and sides to ease up mouse event checking
        rect = self.currentQRubberBand.geometry()
        self.rubberTopLeft = QRect(rect.topLeft(), QSize(8, 8))
        self.rubberTopRight = QRect(rect.topRight(), QSize(-8, 8)).normalized()
        self.rubberBottomRight = QRect(rect.bottomRight(), QSize(-8, -8)).normalized()
        self.rubberBottomLeft = QRect(rect.bottomLeft(), QSize(8, -8)).normalized()
        self.rubberLeft = QRect(self.rubberTopLeft.bottomLeft(), self.rubberBottomLeft.topRight())
        self.rubberTop = QRect(self.rubberTopLeft.topRight(), self.rubberTopRight.bottomLeft())
        self.rubberRight = QRect(self.rubberTopRight.bottomLeft(), self.rubberBottomRight.topRight())
        self.rubberBottom = QRect(self.rubberBottomLeft.topRight(), self.rubberBottomRight.bottomLeft())
        self.rubberInnerRect = QRect(self.rubberTop.bottomLeft(), self.rubberBottom.topRight())

    def eventFilter(self, source, event):
        if event.type() in (QEvent.Resize, QEvent.Move):
            self.updateMargins()
        return super(SelectablePixmap, self).eventFilter(source, event)

    def mousePressEvent(self, event):
        pos = event.pos()
        if not self.currentQRubberBand or not pos in self.currentQRubberBand.geometry():
            if pos not in self.pixmapRect:
                self.originQPoint = None
                return
            self.create_selection(pos)
        elif pos in self.rubberTopLeft:
            self.originQPoint = self.currentQRubberBand.geometry().bottomRight()
        elif pos in self.rubberTopRight:
            self.originQPoint = self.currentQRubberBand.geometry().bottomLeft()
        elif pos in self.rubberBottomRight:
            self.originQPoint = self.currentQRubberBand.geometry().topLeft()
        elif pos in self.rubberBottomLeft:
            self.originQPoint = self.currentQRubberBand.geometry().topRight()
        elif pos in self.rubberTop:
            self.originQPoint = self.currentQRubberBand.geometry().bottomLeft()
            self.moveDirection = Qt.Vertical
        elif pos in self.rubberBottom:
            self.originQPoint = self.currentQRubberBand.geometry().topLeft()
            self.moveDirection = Qt.Vertical
        elif pos in self.rubberLeft:
            self.originQPoint = self.currentQRubberBand.geometry().topRight()
            self.moveDirection = Qt.Horizontal
        elif pos in self.rubberRight:
            self.originQPoint = self.currentQRubberBand.geometry().topLeft()
            self.moveDirection = Qt.Horizontal
        else:
            self.rubber_band_offset = pos - self.currentQRubberBand.pos()

    def mouseMoveEvent(self, event):
        pos = event.pos()
        if event.buttons() == Qt.NoButton and self.currentQRubberBand:
            if pos in self.rubberTopLeft or pos in self.rubberBottomRight:
                self.setCursor(Qt.SizeFDiagCursor)
            elif pos in self.rubberTopRight or pos in self.rubberBottomLeft:
                self.setCursor(Qt.SizeBDiagCursor)
            elif pos in self.rubberLeft or pos in self.rubberRight:
                self.setCursor(Qt.SizeHorCursor)
            elif pos in self.rubberTop or pos in self.rubberBottom:
                self.setCursor(Qt.SizeVerCursor)
            elif pos in self.rubberInnerRect:
                self.setCursor(Qt.SizeAllCursor)
            else:
                self.unsetCursor()
        elif event.buttons():
            if self.rubber_band_offset:
                target = pos - self.rubber_band_offset
                rect = QRect(target, self.currentQRubberBand.size())
                # limit positioning of the selection to the image rectangle
                if rect.x() < self.pixmapRect.x():
                    rect.moveLeft(self.pixmapRect.x())
                elif rect.right() > self.pixmapRect.right():
                    rect.moveRight(self.pixmapRect.right())
                if rect.y() < self.pixmapRect.y():
                    rect.moveTop(self.pixmapRect.y())
                elif rect.bottom() > self.pixmapRect.bottom():
                    rect.moveBottom(self.pixmapRect.bottom())
                self.currentQRubberBand.setGeometry(rect)
            elif self.originQPoint:
                if self.moveDirection == Qt.Vertical:
                    # keep the X fixed to the current right, so that only the
                    # vertical position is changed
                    pos.setX(self.currentQRubberBand.geometry().right())
                else:
                    # limit the X to the pixmapRect extent
                    if pos.x() < self.pixmapRect.x():
                        pos.setX(self.pixmapRect.x())
                    elif pos.x() > self.pixmapRect.right():
                        pos.setX(self.pixmapRect.right())
                if self.moveDirection == Qt.Horizontal:
                    # same as before, but for the Y position
                    pos.setY(self.currentQRubberBand.geometry().bottom())
                else:
                    # limit the Y to the pixmapRect extent
                    if pos.y() < self.pixmapRect.y():
                        pos.setY(self.pixmapRect.y())
                    elif pos.y() > self.pixmapRect.bottom():
                        pos.setY(self.pixmapRect.bottom())
                rect = QRect(self.originQPoint, pos)
                self.currentQRubberBand.setGeometry(rect.normalized())

    def mouseReleaseEvent(self, event):
        self.rubber_band_offset = None
        self.originQPoint = None
        self.moveDirection = 0

尝试这种方式

答案 2 :(得分:0)

您可以这样做。


    class Feed extends Component {
      render() {        
        let newsCards = data.items.map(item => {
            <div className="column is-one-third">
                  <NewsCard
                    article={item}
                    title={item.title}
                    description={item.description}
                  />
                </div>
        });

        return (
          <div className="feed">
            <h1>Newsfeed</h1>
            <div className="columns is-multiline">
              {newsCards}
            </div>
          </div>
        );
      }
    }