NodeJS 根据最高组件动态设置组件行的高度

3yhwsihp  于 2023-01-16  发布在  Node.js
关注(0)|答案(1)|浏览(162)

我有三个组件,叫做blog卡片,用图片和文本呈现。根据文本的长度,卡片有不同的高度。我想呈现它们,然后得到最高的一个,再重新呈现它们,这样它们都是相同的高度。
这里是页面

import * as React from 'react'
import { SocialIconRow } from '@/components/social-icons'
import BlogPostCard from '@/components/BlogCard'
import Image from 'next/image'
import { useState, useEffect } from 'react'

import { FixedSizeList } from 'react-window'

function BlogPostCardsList({ cards }) {
  const tallestCardHeight = useMemo(() => {
    return Math.max(...cards.map(card => card.height))
  }, [cards])

  return (
    <FixedSizeList
      itemCount={cards.length}
      itemSize={tallestCardHeight}
      width={'100%'}
      height={'100%'}
    >
      {({ index, style }) => <BlogPostCard style={style} {...cards[index]} />}
    </FixedSizeList>
  )
}

export default function MyComponent(props) {
  const [cardHeight, setCardHeight] = useState(null);
const [maxHeight, setMaxHeight] = useState(0);

useEffect(() => {
    const calculateHeight = () => {
        const cards = document.querySelectorAll('.blog-post-card');
        let heights = [];
        cards.forEach(card => {
            heights.push(card.clientHeight);
        });
        setMaxHeight(Math.max(...heights));
    }
    calculateHeight();
    setCardHeight(maxHeight);
}, []);

  return (
    <>
      <div className="container mx-auto flex flex-col">
      <div className="container mx-auto flex">
      <div className="w-1/2 pr-4">
        <div className="text-4xl font-bold">Mike Borman</div>
        <div className="text-lg mt-2">Writer, Content Creator and Developer on Cardano</div>
      </div>
  <div className="w-1/2 flex flex-col justify-center">
    <div className="max-h-48 max-w-48 mx-auto my-auto">
    <Image
      src="/images/myfaceppgray.png"
      alt="Picture of the author"
      className="max-h-48 max-w-48"
      width="150"
      height="150"
      unoptimized={true}
    />
    </div>
    <div className="mt-4">
      <SocialIconRow className="social-icon-row" />
    </div>
  </div>
</div>
<div className="mt-8">
    <div className="text-3xl font-bold">Featured Blogs</div>
    <div className="grid grid-cols-3 gap-4 h-full mt-4 align-items-stretch">
      <div  style={{height: cardHeight}}>
        <BlogPostCard
          title="The Hydra Protocol Family — Scaling and Network Optimization for the Cardano Blockchain"
          slug="the-hydra-protocol-family-scaling-and-network-optimization-for-the-cardano-blockchain"
          imageslug="/images/hydra.png"
          className="blog-post-card"
        />
      </div>
      <div style={{height: cardHeight}}>
        <BlogPostCard
          title="Ouroboros, A deep dive for non PhDs"
          slug="ouroboros-a-deep-dive-for-non-phd"
          imageslug="/images/ourobouros.png"
          className="blog-post-card"
        />
      </div>
      <div className="h-full row-auto" style={{height: cardHeight}}>
        <BlogPostCard
          title="Ouroboros, A deep dive for non PhDs"
          slug="ouroboros-a-deep-dive-for-non-phd"
          imageslug="/images/ourobouros.png"
          className="blog-post-card"
        />
      </div>
  </div>
</div>
</div>
      
      
    </>
  )
}

下面是卡组件:

import React from 'react'
import Link from 'next/link'
import Image from 'next/image'

function BlogPostCard(props) {
  const { title, slug, imageslug } = props

  return (
    <Link href={`/blog/${slug}`}>
    <a className="block flex flex-col justify-between rounded-md border-2 border-teal-400 transition-all duration-300 ease-in-out hover:scale-105 hover:shadow-lg">
    <img className="rounded-t-md h-48 w-full object-cover" src={imageslug} alt="blog post cover" />
    <span className="text-white text-2xl p-4">{title}</span>
    </a>
  </Link>
  )
}

export default BlogPostCard

我试着动态渲染它们,然后设置它们,顺便说一句,我真的不知道我在那里做什么。

xuo3flqw

xuo3flqw1#

实际上,除了一个类之外,所有的类都已经完全用CSS来完成了。只需将h-full添加到BlogPostCard组件的Link内的a标记中。然后,您就可以删除所有的JS。可选地,您还可以删除justify-between或将其更改为justify-stretch,以便博客文章的标题直接位于文章封面图像的下方。
在下面的演示中,你可以点击run code snippet来查看结果。另外,如果你要升级到NextJS 13,值得注意的是你不再需要(事实上也不能有)a标签作为Link的子标签。我建议像我下面所做的那样使用article,无论如何,这在语义上会更正确。

function BlogPage({posts}) {
  return (
    <main className="container mx-auto my-8">
      <div className="flex gap-4">
        <div className="w-1/2">
          <h1 className="text-4xl font-bold">Mike Borman</h1>
          <h2 className="text-lg mt-2">
            Writer, Content Creator and Developer on Cardano
          </h2>
        </div>
        <div className="w-1/2 flex flex-col justify-center items-center">
          <span className="w-[150px] h-[150px] bg-neutral-300 rounded-full grid place-content-center">author img here</span>
          <span>social row here</span>
        </div>
      </div>
      <section className="mt-8">
        <header>
          <h2 className="text-3xl font-bold">Featured Blogs</h2>
        </header>
        <div className="grid grid-cols-3 gap-4 h-full mt-4 align-items-stretch">
          {posts.map((post) => (
            <BlogPostCard key={post.id} {...post} />
          ))}
        </div>
      </section>
    </main>
  ) 
}

function BlogPostCard({ slug, imageslug, title,}) {
  return (
    <Link href={`/blog/${slug}`}>
      <article className="flex flex-col justify-stretch h-full rounded-md border-2 border-teal-400 bg-neutral-600 transition-all duration-300 ease-in-out hover:scale-105 hover:shadow-lg">
        <img
          className="rounded-t-md h-48 w-full object-cover"
          src={imageslug}
          alt="blog post cover"
        />
        <span className="text-white text-2xl p-4">{title}</span>
      </article>
    </Link>
  )
}

/* Stubbing out next/link here since I can't run NextJS in code snippets */
function Link({ href, children, className }) {
  return (
    <a href={href} className={className}>
      {children}
    </a>
  )
}

const root = ReactDOM.createRoot(document.getElementById("root"))
root.render(<BlogPage posts={[
  {
    id: 1,
    title: 'The Hydra Protocol Family — Scaling and Network Optimization for the Cardano Blockchain',
    slug: 'the-hydra-protocol-family-scaling-and-network-optimization-for-the-cardano-blockchain',
    imageslug: 'https://d3lkc3n5th01x7.cloudfront.net/wp-content/uploads/2019/05/15233606/700-X-394.png',
  },
  {
    id: 2,
    title: 'Ouroboros, A deep dive for non PhDs',
    slug: 'ouroboros-a-deep-dive-for-non-phd',
    imageslug: 'https://www.almaviva.it/dam/jcr:6212e8ef-1ed6-40e2-a75f-b6fa7c814662/Blockchain_1280x720.jpg',
  },
  {
    id: 3,
    title: 'How Blockchain Is Used',
    slug: 'how-blockchain-is-used',
    imageslug: 'https://imageio.forbes.com/specials-images/imageserve/5f2a32ee3b52675a453e2881/Fascinating-Examples-Of-How-Blockchain-Is-Used-In-Insurance--Banking-And-Travel/960x0.jpg?format=jpg&width=960',
  },
]} />
);
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.development.js"></script>
<div id="root"></div>

相关问题