Search code examples
reactjsnext.jsselectdrop-down-menu

Shadcn/ui Select - change state when user selects item


I am using shadnui and trying to do something very simple > make the user choose from a list of 1 to 6. I want to update the state when the user selects a number.

I found this thread Shadcn ui select component state not updating after change So i tried this:

"use client"
import { useState } from "react"
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select"


export default function Home() {

  const [practices, setPractices] = useState(1)

  return (
    <>
      <h1>{practices}</h1>
      <div className="flex justify-between w-2/3">Aantal praktijken
      <Select>
  <SelectTrigger className="w-[60px]">
    <SelectValue placeholder="0" />
  </SelectTrigger>
  <SelectContent>
    <SelectItem defaultValue="1" onValueChange={() => ( value=> setPractices(value))}>1</SelectItem>
    <SelectItem value="2" onValueChange={() => ( value=> setPractices(value))} >2</SelectItem>
    <SelectItem value="3" onValueChange={() => ( value=> setPractices(value))} >3</SelectItem>
    <SelectItem value="4" >4</SelectItem>
    <SelectItem value="5" >5</SelectItem>
    <SelectItem value="6" >6</SelectItem>
  </SelectContent>
</Select></div>
    </>
  );
}

It doesn't work. Anyone any idea? I've tried a bunch of things.


Solution

  • onValueChange should be given to the <Select>. You can find in the Radix UI docs which shad-cn uses behind the hood.

    It sends a string value so you will either have to parse to int before setting the state or just have the state as a string type.

    that is

      const [practices, setPractices] = useState(1);
    
      const handleStringToInt = (value: string) => {
        setPractices(parseInt(value))
      }
    
    ...
            <Select onValueChange={handleStringToInt}>
              <SelectTrigger className="w-[60px]">
                <SelectValue placeholder="0" />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="1">1</SelectItem>
                <SelectItem value="2">2</SelectItem>
                <SelectItem value="3">3</SelectItem>
                <SelectItem value="4">4</SelectItem>
                <SelectItem value="5">5</SelectItem>
                <SelectItem value="6">6</SelectItem>
              </SelectContent>
            </Select>
    
    

    or

      const [practices, setPractices] = useState("1");
    
      <Select onValueChange={setPractices}>
    

    <Select onValueChange={setPractices}> is equivlent to <Select onValueChange={(val) => setPractices(val)}> here

    Stackblitz