0

I am using latest Next.js app router version. When I load data in my component it initially renders infinite I don't know why. I have valid data.

SidebarContent.tsx

"use client";
import { useEffect, useState } from "react";
import SlidebarItems from "./SlidebarItems";

export default function SlidebarContent() {
  const [content, setContent] = useState<any>([]);

  useEffect(() => {
    async function getData() {
      const res = await fetch("/api");
      const data = await res.json();
      setContent(data);
    }
    getData();
  }, []);

  const selectItem = (id: string) => {
    const newContent = content.map((item) => {
      if (item.id === id) {
        return { ...item, show: true };
      } else {
        return { ...item, show: false };
      }
    });
    setContent(newContent);
  };
  console.log("renders content");

  return (
    <div className="flex justify-between items-center h-full w-full">
      <div className="sliderRef flex gap-2 items-center h-full w-[85%] overflow-x-hidden">
        hi
        {content &&
          content.map((item) => (
            <SlidebarItems
              key={item.id}
              content={item}
              onClick={(id) => selectItem(id)}
            />
          ))}
      </div>
    </div>
  );
}

SidebarItems.js

"use client";
import Image from "next/image";
const SlidebarItems = async ({ content, onClick }) => {
  return (
    <div
      className={`slidebar-content ${content.show ? "selected" : ""}`}
      onClick={() => onClick(content.id)}
    >
      <div className="flex flex-col items-center w-[98px] ">
        <Image
          src={content.src}
          alt={content.title}
          width={24}
          height={24}
          priority
          className="h-7 w-7 mb-2 "
        />
        <h3 className="text-xs font-medium">{content.title}</h3>
      </div>
    </div>
  );
};

export default SlidebarItems;

When I add React Suspense it works fine but I don't want React Suspense to use because when it re-renders it shows fallback component. I want to use this as normal re-render not infinite.

greybeard
  • 2,249
  • 8
  • 30
  • 66
Bidhanz
  • 3
  • 1
  • https://codesandbox.io/p/sandbox/wizardly-microservice-3sw3jj?file=%2Fcomponents%2FSlidebarContent.tsx%3A12%2C24 – Bidhanz Jun 24 '23 at 08:27
  • useEffect is called only once in any case with an empty dependency array, when the component is mounted. But that does not mean the whole render function of the component is called only once as well – astoiccoder Jun 24 '23 at 11:17

1 Answers1

1

In your SidebarItems.js you define the functional component as async.

That makes the function return a promise, which is causing this weird endless re-rendering. Removing the async fixed the issue.


However in your example, I also got some error regarding loading the images

Error: Invalid src prop (https://img.icons8.com/ios/50/key.png) on `next/image`, hostname "img.icons8.com" is not configured under images in your `next.config.js`

which you might have to fix as well. Temporarily fixed it with the loader prop to see if the re-rendering issue really was fixed in the example.

astoiccoder
  • 143
  • 5