根据props名称映射数组,ReactJS

IT技术 javascript reactjs
2021-05-03 12:04:20

我试图从我导入的 js 文件中映射两个数组之一ProductInformation.js

这是在我的主要组件类中<ProductSquare arrayId = {door}/> 我也尝试过<ProductSquare arrayId = {['door']}/>

我想要做的只是映射与panelIdprop 变量匹配的数组(两者中的)

我得到一个错误 TypeError: Cannot read property 'map' of undefined

export const door = [
  {
    id: 1,
    productSquareId: 'door',
    productImage: require('./door.png'),
    companyImage: require('./logo.png'),
    price: '$55.99',

  },
  {
    id: 2,
    productSquareId: 'door',
    productImage: require('./door.png'),
    companyImage: require('./logo.png'),
    price: '$55.99',

  },
  ]
  
  export const lighting = [
  {
    id: 1,
    productSquareId: 'lighting',
    productImage: require('./lighting.png'),
    companyImage: require('./logo.png'),
    price: '$55.99',

  }

import React, { Component } from 'react';
import './ProductSquare.css';
import './grid-container.css'
import  {door, lighting} from './ProductInformation.js';


class ProductSquare extends Component {

constructor(props)
{
  super(props)
    this.state = {
    };
}

PopulateProductSquares()
{

  const ProductSquares = this.props.arrayId.map((product, i) =>
    <div className = "ProductSquare">
    <img  className = "MainImage" src ={this.props.arrayId[i].productImage}  alt = "test"/>
    <img  className = "CompanyImage" src ={this.props.arrayId[i].companyImage} alt = "test"/>

      <button className = "AddButton">
        Add 
      </button>

      <button className = "InfoButton">
        Info
      </button>

    </div>
  )

  return (
     ProductSquares
  )
}


  render() {
    return (
      this.PopulateProductSquares()
    )

}
}

export default ProductSquare;

2个回答

正如 Alan 指出的那样,我认为主要的问题是当您提到 时this,它并未绑定到主要组件。对于不属于标准的一部分官能团react组件的生命周期(constructorrendercomponentDidMount等),你必须明确说明您将其绑定到这样的组件

constructor(props)
{
  super(props)
    this.state = {};

    this.PopulateProductSquares = this.PopulateProductSquares.bind(this);
}

这本身应该可以解决您面临的紧迫问题。

此外,我会指出一些可以使您的组件更易于阅读的事情。例如,内部函数PopulateProductSquares以大写字母开头,让我们认为它是一个类或组件,所以我会重命名它populateProductSquares(或者renderProductSquares我个人认为以表明它的作用)。

其次,当你通过产品循环,你不需要提及this.props.arrayId[i],因为每个对象为已经通过product在函数的参数(product, i) =>,当您使用map

而且您不需要将结果分配this.props.arrayId.map(...)给一个常量,因为您会立即返回它。

最后,由于您在该render方法中所做的唯一一件事就是调用该PopulateProductSquares函数,因此将其分成一个单独的函数是没有意义的,您可以直接将其全部写入render(正如 Alan 所指出的)。但是在很多有用的情况下,您确实希望将它放在一个单独的函数中,因此我认为了解绑定函数的要求很重要。

总而言之,这就是我可能是如何做到的(当您可能想要拥有单独的功能时,使用稍微不同的渲染功能来展示)。

class ProductSquare extends Component {

  constructor(props)
  {
    super(props)
    this.state = {};

    this.renderProductSquares = this.renderProductSquares.bind(this);
  }

  renderProductSquares()
  {
    return this.props.arrayId.map((product, i) =>
      <div className = "ProductSquare" key={i}>
        <img  className = "MainImage" src ={product.productImage}  alt = "test"/>
        <img  className = "CompanyImage" src ={product.companyImage} alt = "test"/>

        <button className = "AddButton">
          Add 
        </button>

        <button className = "InfoButton">
          Info
        </button>
      </div>
    );
  }

  render() {
    return (
      <div>
        <h1>Here are a bunch of product squares</h1>
        {this.renderProductSquares()}
      </div>
    );
  }
}

export default ProductSquare;

我会尝试一下你在这里尝试做的事情:

<ProductSquare arrayId="door" />

为了访问door您的ProductInformation.js文件数组,最好有一个default export

/* ProductInformation.js */
export default {
  door: [/* ...door info*/]
  window: [/* ...window info */],
};

然后当你导入它时,你会:

import products from "./ProductInformation.js";

对于您的map功能,您希望将products导入与您的props.arrayId

const ProductSquares = products[this.props.arrayId].map(...);

在您当前的代码中,您试图映射传递给组件的字符串 prop。您想要的是索引正确的产品数组。您需要创建default export(上面写的),或者在渲染函数中创建一个地图:

const productMap = { door: door, window: window };
const ProductSquares = productMap[this.props.arrayId].map(...);