简体   繁体   English

如何使用反应引导程序和网格水平显示 3 个卡片组件?

[英]How do I display 3 card components horizontally with react bootstrap and grids?

db.json db.json

{
  "products": [
    {
      "id": 1,
      "name": "Moto G5",
      "quantity": 2,
      "price": 13000
    },
    {
      "id": 2,
      "name": "Racold Geyser",
      "quantity": 3,
      "price": 6000
    },
    {
      "id": 3,
      "name": "Dell Inspiron",
      "quantity": 4,
      "price": 50000
    },
    {
      "id": 4,
      "name": "Epson Printer",
      "quantity": 1,
      "price": 9500
    },
    {
      "name": "Lenovo G50",
      "quantity": 2,
      "price": 50000,
      "id": 5
    }
  ]
}

App.js应用程序.js

import React from 'react';
import {BrowserRouter as Router, Route, Switch, NavLink} from 'react-router-dom';
import AllProductsPage from './components/AllProductsPage';
import AddProductPage from './components/AddProductPage';
import ProductDetail from './components/ProductDetail';
import './App.css'
import {Provider} from 'react-redux';
import configureStore from './stores/configureStore';
import {loadProduct} from './actions/productActions';

export default class App extends React.Component {
  render() {

       const About=()=>(
              <div>
                  <h1>About : This application provides information about the products </h1>
              </div>
      );

      const Header = ()=>(
        <header>
            <NavLink to="/about" activeClassName="is-active" >About</NavLink>
            <NavLink to="/" exact={true} activeClassName="is-active" >Products</NavLink>
        </header>
    );

       
      const store = configureStore();
      //loading data from db.json and into the store through the reducers
      store.dispatch(loadProduct());

      return (
        <Provider store={store}>
          <Router>
              <Header/>
              <Switch>
                <Route path="/" exact={true} component={AllProductsPage} />
                <Route path="/about"  component={About}/>
                <Route path="/addProduct" component={AddProductPage} />
                <Route path="/ProductDetail" component={ProductDetail}/>
              </Switch>
          </Router>
        </Provider>
      );
  }
}

AllProductsPage.js AllProductsPage.js

import React, { Component } from "react";
import { connect } from "react-redux";
import { bindActionCreators } from "redux";
import { Link } from "react-router-dom";
import ProductList from "./ProductList";
import * as productActions from "../actions/productActions";
import { Button } from "react-bootstrap";

class AllProductsPage extends Component {
  render() {
    return (
      <div>
        <h1>Product List - Using Redux</h1>
        <ProductList products={this.props.products} />
        <br />
        <Link to="/addProduct"><Button variant="primary">Add Product</Button>{" "}</Link>
      </div>
    );
  }
}

function mapStateToProps(state, ownProps) {
  return {
    products: state.products,
  };
}

function mapDispatchToProps(dispatch) {
  return {
    actions: bindActionCreators(productActions, dispatch),
  };
}

export default connect(mapStateToProps, mapDispatchToProps)(AllProductsPage);

ProductList.js产品列表.js

import React from "react";
import Product from "./Product";
import { Container, Row, Col} from "react-bootstrap";

export default class ProductList extends React.Component {
  render() {
    var productNodes = this.props.products.map((product) => {
      return (
        <Product
          key={product.id}
          id={product.id}
          name={product.name}
          quantity={product.quantity}
          price={product.price}
        >
          {product.text}
        </Product>
      );
    });
    return (
      <div>
        <Container>
          <Row>
          <Col xs="4">
                {productNodes}
              </Col>
          </Row>
        </Container>
      </div>
    );
  }
}

Product.js产品.js

import React from "react";
import { Link } from "react-router-dom";
import { Prompt } from "react-router";
import { Card, Button } from "react-bootstrap";
export default class Comment extends React.Component {
  // eslint-disable-next-line
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <Card style={{ width: "18rem" }}>
      <Prompt message={location =>location.pathname.includes("/ProductDetail")?  `Are you sure you want to view the details ?` : true  } />
        <Card.Body>
          <Card.Title>
            {this.props.name}
          </Card.Title>
          <Card.Text>
            Quantity : {this.props.quantity}
          </Card.Text>
          <Card.Title>{this.props.price}</Card.Title>
          <Link to={{pathname: "/ProductDetail",productName:{name : this.props.name}}}>
            <Button variant="primary">View Product</Button>
          </Link>
        </Card.Body>
      </Card>
    );
  }
}

Now this is my first time using react-bootstrap.现在这是我第一次使用 react-bootstrap。 So i don't have much clue here.所以我在这里没有太多线索。

What i want is like for the cards to be generated in such a way that there should be THREE cards in a row.我想要的是生成卡片的方式应该是连续三张卡片。

Now this is the code i've done so far, but I am confused on how i can make the cards horizontal, without writing <Col> three times, which repeats the same component 3 times in a row.现在这是我到目前为止所做的代码,但我对如何使卡片水平而不写<Col>三次感到困惑,这会连续重复相同的组件 3 次。 Please help.请帮忙。

You need to split the data into rows, each one containing 3 cols, each one containing a product.您需要将数据分成几行,每行包含 3 列,每列包含一个产品。 You can solve this problem by using a chunk function , which takes an array and a chunk size as parameters and outputs an array containing all the chunks.您可以通过使用块 function来解决此问题,该块将数组和块大小作为参数并输出包含所有块的数组。 There are many libraries that implement this (eg lodash) but for the sake of simplicity, just grab the chunk function from here .有很多库实现了这一点(例如 lodash),但为了简单起见,只需从此处获取块 function。

Solution解决方案

  1. Copy or import a chunk function from a well-known library.从知名库中复制或导入块 function。
const chunk = (arr, chunkSize = 1, cache = []) => {
  const tmp = [...arr]
  if (chunkSize <= 0) return cache
  while (tmp.length) cache.push(tmp.splice(0, chunkSize))
  return cache
}
  1. Split your data into chunks of a fixed length.将数据拆分为固定长度的块。
const productsChunks = chunk(props.products, 3);
  1. Render each chunk as a row containing 3 columns, with your Product component inside.将每个块渲染为包含 3 列的行,其中包含您的 Product 组件。
const rows = productsChunks.map((productChunk, index) => {
    const productsCols = productChunk.map((product, index) => {
        return (
        <Col xs="4" key={product.id}>
          <Product key={product.id} quantity={product.quantity} price={product.price} name={product.name} />      
        </Col>
      );
    });
    return <Row key={index}>{productsCols}</Row>
});

That should solve your problem, let me know what you think about my solution.那应该可以解决您的问题,让我知道您对我的解决方案的看法。 I've included a JSFiddle for clarity.为了清楚起见,我包含了一个 JSFiddle。 My JSFiddle: Link我的 JSFiddle:链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM