如何使用反应引导程序和网格水平显示 3 个卡片组件? [英] How do I display 3 card components horizontally with react bootstrap and grids?

查看:18
本文介绍了如何使用反应引导程序和网格水平显示 3 个卡片组件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

db.json

<代码>{产品":[{id":1,名称":Moto G5",数量":2,价格":13000},{id":2,名称":拉科尔德间歇泉",数量":3,价格":6000},{id":3,名称":戴尔 Inspiron",数量":4,价格":50000},{id":4,名称":爱普生打印机",数量":1,价格":9500},{名称":联想 G50",数量":2,价格":50000,id":5}]}

App.js

从'react'导入React;从react-router-dom"导入 {BrowserRouter 作为路由器、路由、交换机、NavLink};从 './components/AllProductsPage' 导入 AllProductsPage;从 './components/AddProductPage' 导入 AddProductPage;从 './components/ProductDetail' 导入 ProductDetail;导入'./App.css'从'react-redux'导入{Provider};从 './stores/configureStore' 导入 configureStore;从'./actions/productActions'导入{loadProduct};导出默认类 App 扩展 React.Component {使成为() {const 关于=()=>(<div><h1>About:此应用程序提供有关产品的信息 </h1>

);const 标题 = ()=>(<标题><路线路径="/about";组件={关于}/><路由路径="/addProduct";组件={AddProductPage}/><Route path="/ProductDetail";组件={ProductDetail}/></开关></路由器></提供者>);}}

AllProductsPage.js

import React, { Component } from "react";从react-redux"导入{连接};从redux"导入 { bindActionCreators };从react-router-dom"导入{链接};从./ProductList"导入产品列表;import * as productActions from "../actions/productActions";从react-bootstrap"导入{按钮};类 AllProductsPage 扩展组件 {使成为() {返回 (<div><h1>产品列表 - 使用 Redux</h1><ProductList products={this.props.products}/><br/><链接到=/addProduct"><按钮变体=主要">添加产品</按钮>{""}</链接>

);}}函数 mapStateToProps(state, ownProps) {返回 {产品:state.products,};}函数 mapDispatchToProps(dispatch) {返回 {动作:bindActionCreators(productActions, dispatch),};}导出默认连接(mapStateToProps,mapDispatchToProps)(AllProductsPage);

ProductList.js

从react"导入 React;从./Product"导入产品;从反应引导"导入{容器,行,列};导出默认类 ProductList 扩展 React.Component {使成为() {var productNodes = this.props.products.map((product) => {返回 (<产品键={product.id}id={product.id}名称={产品名称}数量={产品.数量}价格={产品.价格}>{产品.文本}</产品>);});返回 (<div><容器><行><Col xs=4">{产品节点}</Col></行></容器>

);}}

Product.js

从react"导入 React;从react-router-dom"导入{链接};import { Prompt } from react-router";从react-bootstrap"导入{卡片,按钮};导出默认类 Comment extends React.Component {//eslint-disable-next-line构造函数(道具){超级(道具);}使成为() {返回 (<卡片样式={{宽度:18rem";}}><提示消息={location =>location.pathname.includes(/ProductDetail")?`您确定要查看详细信息吗?` : true }/><卡片体><卡片标题>{this.props.name}</卡片标题><卡片文本>数量:{this.props.quantity}</卡片文本><Card.Title>{this.props.price}</Card.Title><Link to={{pathname: "/ProductDetail",productName:{name : this.props.name}}}><按钮变体=主要">查看产品</按钮></链接></Card.Body></卡片>);}}

这是我第一次使用 react-bootstrap.所以我在这里没有太多线索.

我想要的是卡片的生成方式应该是连续三张卡片.

现在这是我到目前为止所做的代码,但我对如何使卡片水平而不写 3 次(重复相同的组件 3)感到困惑连续几次.请帮忙.

解决方案

需要将数据拆分成行,每行包含 3 个列,每列包含一个产品.您可以使用 chunk 函数 来解决这个问题,该函数以一个数组和一个块大小作为参数,并输出一个包含所有块的数组.有许多库实现了这个(例如 lodash),但为了简单起见,只需从 这里获取块函数.

解决方案

  1. 从知名库中复制或导入块函数.

const chunk = (arr, chunkSize = 1, cache = []) =>{const tmp = [...arr]if (chunkSize <= 0) 返回缓存while (tmp.length) cache.push(tmp.splice(0, chunkSize))返回缓存}

  1. 将数据拆分为固定长度的块.

const productsChunks = chunk(props.products, 3);

  1. 将每个块渲染为包含 3 列的行,其中包含您的 Product 组件.

const rows = productsChunks.map((productChunk, index) => {const productsCols = productChunk.map((product, index) => {返回 (<Col xs=4"键={product.id}><Product key={product.id}quantity={product.quantity} price={product.price} name={product.name}/></Col>);});return {productsCols}});

那应该可以解决您的问题,请告诉我您对我的解决方案的看法.为了清楚起见,我已经包含了一个 JSFiddle.我的 JSFiddle:链接

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

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

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

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

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. 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. Please help.

解决方案

You need to split the data into rows, each one containing 3 cols, each one containing a product. 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. There are many libraries that implement this (e.g. lodash) but for the sake of simplicity, just grab the chunk function from here.

Solution

  1. Copy or import a chunk function from a well-known library.

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.

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. My JSFiddle: Link

这篇关于如何使用反应引导程序和网格水平显示 3 个卡片组件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆