首页 > 解决方案 > 对于这个例子,如何在 React 中思考:我应该将重复的 html 标记存储在 Array 中并将其导入到类组件中吗?

问题描述

我正在制作我的作品集,我有一页列出了我所有的存档项目。我有10多个项目。每个项目看起来都完全相同,只是使用了 diff info/images:

<div>
  <h1> Title </h1>
  <h1> Image </h1>
  <h1> Tech Stack </h1>
  <button onClick={()=> this.expandDropdown()}>Tech Stack</button>
</div>

onClick 按钮触发一个函数,将 expand 的状态从 false 更改为 true:

  expandDropdown =()=> {
this.setState({
  expand: !this.state.expand
})
  }

它在冒泡(?),所以当我单击一个按钮时,它们都会展开。我的代码是 245 行,我认为这太长了,所以与其制作一个数组来模拟我拥有的项目数量或为每个项目硬编码一个 ID,我该如何简化我的代码?我觉得我应该导入项目列表,然后映射它们。我不确定如何前进。

编辑:目录:

我正在使用 react-router-dom 所以父级只是我的切换页面,它不处理状态。我有:

|App.js
   |- Switch Page (router)
      | -- Best Projects(managing state)
      | -- Career Timeline
      | -- Archived Projects(managing state) <- expansion is here w/all projects

“最佳项目”和“归档项目”都是类。

编辑 2:导出项目:

    import React from "react";
import profilePhoto from "../../photos/IMG_2881.JPG";
import salAndCheong from "../../photos/salAndCheong.jpg";
import byeSal from "../../photos/goodByeSal.jpg";
import bike from "../../photos/bike.jpg";
import style from '../../styles/main.module.css'


    export default{

compo: [
    <img onMouseEnter={()=>this.imageHover()} onMouseOut={()=>this.imageHover()} className={style.noHover} src='../../photos/IMG_2881.JPG' alt="" />,
    <img onMouseEnter={()=>this.imageHover()} onMouseOut={()=>this.imageHover()} className={style.noHover} src={salAndCheong} alt="" />,
    <img onMouseEnter={()=>this.imageHover()} onMouseOut={()=>this.imageHover()} className={style.noHover} src={bike} alt="" />,
    <img onMouseEnter={()=>this.imageHover()} onMouseOut={()=>this.imageHover()} className={style.noHover} src={byeSal} alt="" />,
  ]
}e

标签: reactjs

解决方案


  1. 数据:将您的投资组合数据添加到数组中并导出,将其视为 api

  2. 父组件:将您的投资组合数据导入容器父组件并通过它进行映射,传递道具

  3. 子组件:将您的投资组合外推到一个单独的展示组件中,该组件将接收道具

  4. Scope :在这个展示组件中渲染 props 并处理任何其他事件处理程序来确定它的范围(你也可以这样对待状态)

投资组合 API

// portfolios-data.js
import image0 from "../src/assets/images/image0.jpg";
import image1 from "../src/assets/images/image1.jpg";
import image2 from "../src/assets/images/image2.jpg";
import image3 from "../src/assets/images/image3.jpg";

export const portfoliosData = [
  {
    id: 0,
    title: 'portfolio 0',
    image: image0,
    techStack: 'Foo, Bar, Baz',
  },
  {
    id: 1,
    title: 'portfolio 1',
    image: image1,
    techStack: 'Foo, Bar, Baz',
  },
  {
    id: 2,
    title: 'portfolio 2',
    image: image2,
    techStack: 'Foo, Bar, Baz',
  },
  {
    id: 3,
    title: 'portfolio 3',
    image: image3,
    techStack: 'Foo, Bar, Baz',
  },
]

包含组件的项目

// Projects.js container component
import React from "react";
// Utils
import { portfoliosData } from "../../utils/portfolios-data"; // ./src/utils/
// Components
import Protfolio from "../presentational/Protfolio"; // ./src/components/presentational

export default function Projects() {

  return (
    <div className="projects">
      <h2>Projects</h2>
      <ul className="portfolioList">
        {portfoliosData.map(portfolio => {
          <li key={portfolio.id}><Protfolio props={portfolio} /></li>
        })}
      </ul>
    </div>
  );
}

投资组合子组件

// Portfolio.js presentational component
import React from "react";

export default function Portfolio(props) {

  const { 
    title,    // string
    image,    // string (filepath)
    techStack // string
  } = props;

  // scoped event handlers
  const expandDropdown = () => {
    /* ... */
  }

  // keep html semantic, only h1 per page, keep h2s at a minimum
  return (
    <div className="portfolio">
      <h3>{title}</h3>
      <img src={image} alt={title} />
      <h4>{techStack}</h4>
      <button onClick={() => expandDropdown()}>Tech Stack</button>
    </div>
  );
}

推荐阅读