首页 > 解决方案 > 如何使用单个键渲染组件?

问题描述

我有一个仪表板,我想使用React-Grid-Layout,但我只在组件被收藏时才渲染它们。要使用网格布局,每个 div 都需要一个key="a"key="b"根据定义的布局,每个键都需要不同。

我怎样才能给每个 div 一个单独的键?当它以当前形式呈现在屏幕上时,它会使用相同的卡片呈现两个 div,我需要它为每张卡片呈现一个 div。

  const layout = [
    { i: "a", x: 0, y: 0, w: 1, h: 2 },
    { i: "b", x: 1, y: 0, w: 3, h: 2, minW: 2, maxW: 4 },
    { i: "c", x: 4, y: 0, w: 1, h: 2 },
  ];

渲染函数

  const userHasFavorite = (data, favIds, layout) => {
  if (favIds && data) {
    const filteredData = data.filter((idsArr) =>
      favIds.split(",").includes(idsArr.id)
    );
    const keysMapped = layout.map((ids) => ids.i);
    console.log(keysMapped);
    return (
      <div key={keysMapped}>
        <PriceCard data={filteredData} />
      </div>
    );
  } else {
    return <p1>No Cards Have Been Faved</p1>;
  }
};

网格布局

 <GridLayout
          className="layout"
          layout={layout}
          cols={12}
          rowHeight={30}
          width={1200}
        >
          {isLoading ? (
            <LoadingCard />
          ) : (
            userHasFavorite(data, favoritedIds, layout)
          )}
  </GridLayout>

价格卡

 return (
    <dl className="mt-5 ml-5 grid grid-cols-1 gap-5 sm:grid-cols-2 lg:grid-cols-3">
      {data.map((item) => (
        <div
          key={item.id}
          className="flex-row bg-white hover:bg-gray-100 dark:hover:bg-purple-700  dark:bg-secondaryDark h-24 pt-2 px-4 pb-12 sm:pt-6 sm:px-6 shadow-2xl  rounded-lg overflow-hidden"
        >
          <div className="flex h-2 ">
            {/* TODO: ADD TRANSISITON   */}
            {cardFaved.some((cardFaved) => cardFaved.id === item.id) ? (
              <MinusSmIcon
                onClick={() => removeCardFavClick(item.id)}
                className="ml-auto h-5 w-5 cursor-pointer fill-current text-red-600 "
              />
            ) : (
              <PlusSmIcon
                onClick={() => handleCardFavClick(item.id)}
                className="ml-auto h-5 w-5  cursor-pointer  fill-current text-green-600 "
              />
            )}
          </div>
          <dt>
            <div className="absolute rounded-md p-3">
              <img className="h-6 w-6 mr-3" src={item.image} />
            </div>
            <p className="ml-16 text-sm pb-0  font-medium text-gray-500 dark:text-white truncate">
              {item.name.toUpperCase()}
            </p>
          </dt>
          <dd className="ml-16 pb-7  flex items-baseline sm:pb-7">
            <p className="text-2xl font-semibold text-gray-900 dark:text-white">
              {formatDollar(item.current_price)}
            </p>
          </dd>
        </div>
      ))}
    </dl>
  );
};

导出默认价格卡;

我遇到的错误是卡片在一个 div 中呈现 2

在此处输入图像描述

错误 2

在此处输入图像描述

标签: javascriptreactjsnext.js

解决方案


好的,所以从React-Grid-Layout 官方的用法来看,
需要map()直接在<GridLayout/>组件内。

所以这里有个很好的建议:

在 GridLayout 中:

  1. 与地图()
<GridLayout className="layout" layout={layout} cols={12} rowHeight={30} width={1200}>
  {isLoading 
    ? <LoadingCard />
    : layout.map(({ i }) => 
        <div key={i}>
          // change this from a typical function into a React component
          <UserHasFavorite data={data} favIds={favoritedIds} />
        </div>
   )}
</GridLayout>
  1. 没有地图()
<GridLayout className="layout" layout={layout} cols={12} rowHeight={30} width={1200}>
  {isLoading 
    ? <LoadingCard />
    : <React.Fragment> 
        <div key="a"><UserHasFavorite data={data} favIds={favoritedIds} /></div>
        <div key="b"><UserHasFavorite data={data} favIds={favoritedIds} /></div>
        <div key="c"><UserHasFavorite data={data} favIds={favoritedIds} /></div>
      </React.Fragment>}
</GridLayout>

在子组件内

const UserHasFavorite = (data, favIds) => {
  if (favIds && data) {
    const filteredData = data.filter((idsArr) =>
      favIds.split(",").includes(idsArr.id)
    );
    // <div> is moved up into the GridLayout
    return <PriceCard data={filteredData} />;
  } else {
    return <p1>No Cards Have Been Faved</p1>;
  }
};

更新:处理渲染多个“相似”卡片的问题

  • 在 PriceCard 中,有这个...
return (
    <dl className="mt-5 ml-5 grid grid-cols-1 gap-5 sm:grid-cols-2 lg:grid-cols-3">
      {data.map((item) => (
        <div
          key={item.id}
          className="flex-row bg-white hover:bg-gray-100 dark:hover:bg-purple-700  dark:bg-secondaryDark h-24 pt-2 px-4 pb-12 sm:pt-6 sm:px-6 shadow-2xl  rounded-lg overflow-hidden"
        >
        </div>
       )}
   </dl>
)

您正在映射以连续显示所有卡片。因此,如果您更新了className="flex-column..."这两张卡,则应该在一个 Column 中呈现,但在一个中呈现<div>

然后,如果你这样做,你有两个选择:

  1. 要么你删除<GridLayout/>并像这样直接渲染......
 // <GridLayout className="layout" layout={layout} cols={12} rowHeight={30} width={1200}>
 return (
   isLoading 
     ? <LoadingCard />
     : <UserHasFavorite data={data} favIds={favoritedIds} />
 )
 // </GridLayout>

通过删除<GridLayout/>用于显示的内容,您将在一列中仅呈现两张卡片(由PriceCard组件处理)。

2.或者直接渲染<PriceCard/>到这样的内部...


// Parent component -> GridLayout
export const ParentComponent = props => {

  // I'm not sure where "data" and "favoritedIds" are coming from yet,
  // but we check like "data &&..." to ensure they are defined 
  // before we attempt to filter
   
  const filteredData = data && data.filter(
    (idsArr) => favoritedIds && favoritedIds.split(",").includes(idsArr.id)
  );

  return (
    <GridLayout className="layout" layout={layout} cols={12} rowHeight={30} width={1200}>
     {isLoading 
       ? <LoadingCard />
       : (!!data && !!filteredData)
         ?  <React.Fragment> 
              <div key="a"><PriceCard data={filteredData[0]} /></div>
              <div key="b"><PriceCard data={filteredData[1]} /></div>
              <div key="c"><PriceCard data={filteredData[2]} /></div>
            </React.Fragment>}
         : <p1>No Cards Have Been Faved</p1>
    </GridLayout>
  )
}

// Child component -> PriceCard
export const ChildComponent = props => {

 return (
    <dl className="mt-5 ml-5 grid grid-cols-1 gap-5 sm:grid-cols-2 lg:grid-cols-3">
      {data && /* don't map here -> we moved it to parent */
        <div className="flex-row bg-white hover:bg-gray-100 dark:hover:bg-purple-700  dark:bg-secondaryDark h-24 pt-2 px-4 pb-12 sm:pt-6 sm:px-6 shadow-2xl  rounded-lg overflow-hidden">
          /* make necessary changes */
        </div>}
   </dl>
 )
}

推荐阅读