You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React按对象索引渲染不同HTML及Meteor布局与标签错误问题

解决Meteor+React的Auctions集合3列布局与HTML标签错误问题

Hey there! Let's tackle your two issues step by step—first fixing that unclosed div error, then getting your auctions into a clean 3-column layout with React and Meteor.

一、修复未闭合div标签的HTML错误

First off, JSX is strict about tag closure—unlike plain HTML, you can't leave a <div> hanging without its corresponding </div>. Here are quick checks to fix this:

  • Double-check all your opening <div> tags to make sure each has a closing </div>.
  • For self-contained elements (like images, inputs), use self-closing syntax: <img src="..." alt="..." /> instead of <img src="..." alt="...">.
  • If you're using conditional rendering, ensure that every branch of your code returns properly closed elements.

二、实现3列响应式布局渲染Auctions集合

Forget manually tracking indexes to group items—CSS Grid is the easiest way to create a 3-column, auto-row layout. Here's a complete, fixed version of your App.js that implements this:

import React, { Component } from 'react';
import { withTracker } from 'meteor/react-meteor-data';
import { Auctions } from '/imports/api/auctions'; // Adjust this path to your actual collection import

class App extends Component {
  render() {
    const { loading, auctions } = this.props;

    // Show loading state while data is fetching
    if (loading) return <div className="loading">Loading auctions...</div>;

    return (
      <div className="auctions-container">
        <h1>Active Auctions</h1>
        {/* Grid container for 3-column layout */}
        <div className="auctions-grid">
          {auctions.map(auction => (
            <div key={auction._id} className="auction-card">
              <h3>{auction.title}</h3>
              <p>Current Price: ${auction.currentPrice}</p>
              <p>Ends: {new Date(auction.endDate).toLocaleString()}</p>
              {/* Add any other auction fields you need here */}
            </div>
          ))}
        </div>
      </div>
    );
  }
}

// Wrap component with Tracker to fetch Meteor data
export default withTracker(() => {
  // Subscribe to the auctions collection
  const subscription = Meteor.subscribe('auctions');
  
  return {
    loading: !subscription.ready(),
    auctions: Auctions.find({}).fetch() // Fetch all auction documents
  };
})(App);

Add this CSS (either in a separate file or inline)

.auctions-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr); /* 3 equal-width columns */
  gap: 1.5rem; /* Space between cards */
  padding: 1rem;
}

.auction-card {
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  padding: 1rem;
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

.auctions-container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 2rem;
}

.loading {
  text-align: center;
  padding: 2rem;
  font-size: 1.2rem;
}

/* Optional: Make it responsive for smaller screens */
@media (max-width: 768px) {
  .auctions-grid {
    grid-template-columns: repeat(2, 1fr); /* 2 columns on tablets */
  }
}

@media (max-width: 480px) {
  .auctions-grid {
    grid-template-columns: 1fr; /* 1 column on mobile */
  }
}

Key details explained:

  • withTracker: This connects your React component to Meteor's data layer, handling subscriptions and data fetching automatically. We check if the subscription is ready to show a loading state.
  • CSS Grid: The grid-template-columns: repeat(3, 1fr) rule creates 3 columns that take equal space in the container. Rows are added automatically as more auctions are loaded.
  • Key prop: Always include a unique key when mapping over arrays in React—using the auction's _id (Meteor's auto-generated document ID) is perfect here.

If you insist on grouping items by index (e.g., 3 items per row), you can split the auctions array into chunks first:

// Inside your render method
const chunkedAuctions = [];
for (let i = 0; i < auctions.length; i += 3) {
  chunkedAuctions.push(auctions.slice(i, i + 3));
}

return (
  <div className="auctions-container">
    <h1>Active Auctions</h1>
    {chunkedAuctions.map((row, rowIndex) => (
      <div key={rowIndex} className="auction-row">
        {row.map(auction => (
          <div key={auction._id} className="auction-card">
            {/* Auction content */}
          </div>
        ))}
      </div>
    ))}
  </div>
);

Then use Flexbox for the rows:

.auction-row {
  display: flex;
  gap: 1.5rem;
  margin-bottom: 1.5rem;
  justify-content: space-between;
}

.auction-card {
  flex: 1; /* Each card takes equal space in the row */
}

But again, CSS Grid is cleaner and requires less manual code!

内容的提问来源于stack exchange,提问作者Alan Ortega

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 10:01:16