Why my useState in react no next14 application is not working?

Advertisements

I’m currently working on a project, and now I’m creating a Select component using a design pattern that I discovered. The implementation looks great, but something seems to be wrong as the useState doesn’t appear to be working. I’m relatively new to Next.js/React, so maybe it’s a simple logic error.

Here are the main code:

'use client';
import Image from 'next/image';
import { Select } from '@/components/ui/select';
import { ferramentas } from '@/libs/ferramentas';
import { useState } from 'react';
import { Check } from 'lucide-react';

export default function Ferramentas() {
  const [tool, setTool] = useState('');

  const handleSelect = (option: string) => {
    console.log(option);
    setTool(option);
  };

  return (
    <div className="ml-16">
      <Select.Root className="w-[500px]" selected={tool}>
        <Select.Content>
          {ferramentas.map((ferramenta) => (
            <Select.Option key={ferramenta.item_id} onClick={() => handleSelect(ferramenta.item_id)}>
              <div className="flex items-center gap-3">
                <Image alt={ferramenta.name} src={`https://render.albiononline.com/v1/item/${ferramenta.item_id}.png`} width={32} height={32} />
                {ferramenta.name}
              </div>
              {tool === ferramenta.item_id ? <Check /> : null}
            </Select.Option>
          ))}
        </Select.Content>
      </Select.Root>
      <h1>{tool}</h1>
    </div>
  );
}

Select.Root

'use client';
import { SelectProps } from '@/components/global-types';
import { ChevronDown, ChevronUp } from 'lucide-react';
import { useState } from 'react';
import { twMerge } from 'tailwind-merge';

export default function SelectRoot({ className, children, selected, ...props }: SelectProps) {
  const [open, setOpen] = useState(false);

  return (
    <div
      className={twMerge('group rounded relative cursor-pointer h-8 m-5 px-2 flex items-center flex-row-reverse justify-between bg-white', className)}
      onClick={() => setOpen(!open)}
      {...props}
    >
      {open ? <ChevronUp className="group-hover:opacity-70" /> : <ChevronDown className="group-hover:opacity-70" />}

      {selected}

      {open && children}
    </div>
  );
}

Select.Content

import { ReactNode } from 'react';

export default function SelectContent({ children }: { children: ReactNode }) {
  return <div className="absolute top-full left-0 mt-1 overflow-y-scroll h-64 rounded bg-zinc-800 p-2 w-full">{children}</div>;
}

SelectOption

import { OptionProps } from '@/components/global-types';
import { twMerge } from 'tailwind-merge';

export default function SelectOption({ children, className, ...props }: OptionProps) {
  return (
    <div className={twMerge('flex items-center justify-between cursor-pointer hover:bg-zinc-700 text-white h-8 px-2 whitespace-nowrap rounded', className)}>
      {children}
    </div>
  );
}

I tried create a function to setState, or setState directly on onClick but never happens, the states don’t change.

>Solution :

The issue is that you’re passing an onClick prop to the SelectOption component, but it’s not being used.

You need to add it like this:

export default function SelectOption({ children, className, onClick, ...props }: OptionProps) {
  return (
    <div onClick={onClick} className={twMerge('flex items-center justify-between cursor-pointer hover:bg-zinc-700 text-white h-8 px-2 whitespace-nowrap rounded', className)}>
      {children}
    </div>
  );
}

Or spreading the props directly by doing the following:

<div
  className="your-current-classes"
  {…props}
>
  {children}
</div>

Leave a ReplyCancel reply