Search code examples
reactjsnext.jsshadcnuiradix-uitanstack-table

Data-table Filters not working in shadcn-ui/radix-ui dialog component


I'm using the data-table from shadcn-ui when I render it inside a dialog the filters don't work. I'm using radix-ui with shadcn-ui.

I looked in the inspect tab the dialog component is rendered below all the script tags in the body element. Console tab I'm not sure if this is the reason it's not working as it should be.

Here's the link for a dev environment replicating the issue Dev Environment


Solution

  • I see your code and fiddle with it.

    From what I could see, your problems stems from tour DebounceInput components.

    First of all, it doesn't return the correct value when the value change, and there's problem with it's render, I found out that it can trigger continuous re-render.

    In order to solve it, you can change your DebounceInput component to be like this:

    export default function DebounceInput({
      value: initialValue,
      onChange,
      debounce = 500,
      ...props
    }: Props) {
      const [value, setValue] = React.useState(initialValue);
    
      React.useEffect(() => {
        setValue(initialValue);
      }, [initialValue]);
    
      React.useEffect(() => {
        const timeout = setTimeout(() => {
          onChange(value);
        }, debounce);
    
        return () => clearTimeout(timeout);
      // You used to listen to onChange event, I don't know why
      // But I speculate that's the cause of multiple re-rendering
      }, [debounce, value]);
    
      return (
        <Input
          {...props}
          value={value}
          onChange={(e) => setValue(e.target.value)}
        />
      );
    }
    

    And inside your DataTable component, you can create a input change handler function and pass it to the DebounceInput component like this:

    function handleGlobalFilterChange(val: string) {
        setGlobalFilter(val.toString());
    }
    

    And pass it to your DebounceInput component like this:

    <DebounceInput
          debounce={200}
          value={globalFilter}
          onChange={handleGlobalFilterChange}
          className="max-w-sm p-2 mb-2"
          placeholder="Search all columns..."
    />
    

    Also don't forget to infer the new correct type in your DebounceInput component props like this:

    type Props = {
      value: string;
      // This change
      onChange: (value: string) => void;
      debounce?: number;
    } & Omit<React.InputHTMLAttributes<HTMLInputElement>, 'onChange'>;