根据道具名称ReactJS

时间:2018-06-20 23:47:50

标签: javascript reactjs

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

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

我想做的只是映射与panelId prop变量匹配的数组(两个数组中的一个)。

我得到一个错误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 个答案:

答案 0 :(得分:1)

正如艾伦指出的那样,我认为主要的问题是,当您指的是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中(正如艾伦指出的那样)。但是在很多有用的情况下,您确实希望将其包含在单独的函数中,因此我认为了解绑定函数的要求很重要。

总而言之,这就是我的做法(使用稍微不同的渲染功能来展示何时可能需要单独的功能)。

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;

答案 1 :(得分:0)

在这里您将尝试做些什么:

<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(...);