I put JSS styles inside a custom React hook. Is this bad?

307 Views Asked by At

I've been struggling to find a way to make a solid reusable SearchBar Component. I tried to make a component for it. However this component cannot hold its own state. This means you would have two imports to use this search bar. Something like this:

import React, { useState } from 'react';
import SearchBar from './SearchBar';

const Parent = () => {
   const [value, setValue] = useState("");

   return (
      <div>
         <SearchBar ...use 'value' and 'setValue' somehow... blah blah... />
         {list.map((item) => ...render item if it matches 'value'...)}
      </div>

}

That's easy enough but my brain go going... I found a "useInput" custom hook on the internet that uses the spread syntax to pass some props to an 'input' tag... I decided to see just how far I could take this.

As it turns out we are using JSS in our project and this is when things got a little ridiculous. Here is my Hook:

import { useState } from 'react';
import { createUseStyles } from 'react-jss';

// My gut tells my this is a really terrible thing to do! 
export const useSearchBar = () => {
    const [value, setValue] = useState('');
    const classes = useStyles();
    return {
        value,
        setValue,
        reset: () => setValue(""),
        bindSearchBar: {
            type: 'text',
            className: classes.searchBar,
            placeholder: 'Search',
            value,
            onChange: (event: {target: {value: string}}) => {
                setValue(event.target.value);
            }
        }
    };
};

const useStyles = createUseStyles({
    searchBar: {
        ...search bar styles...
    },
});

The simplest implementation looks like this:

import React form 'react';
import { useSearchBar } from '../hooks/useSearchBar';

const Component = () => {

   const { bindSearchBar, value } = useSearchBar();

   return <input {...bindSearchBar} />;

}

I would need a list but I think you get the point. There is this weird feeling I have that there is something terribly wrong with this. I'm pretty sure I'll love it right now but in 6 months I'm going to hate my self. Can anyone tell me what might go wrong here or why this might be bad practice? Or do you think using hooks this way is somewhat viable?

1

There are 1 best solutions below

0
On

There is nothing wrong to create jss classes in a hook. The useStyles is a hook and the attribute of a custom hook is to use other hooks inside it.

Other than that, here is a performance tip.

export const useSearchBar = () => {
    const [value, setValue] = useState('');
    const classes = useStyles();
    
    //wrap with a useMemo to prevent recreation of the props when the container rerender
    const searchBarProps = React.useMemo(()=>({
        value,
        setValue,
        reset: () => setValue(""),
        bindSearchBar: {
            type: 'text',
            className: classes.searchBar,
            placeholder: 'Search',
            value,
            onChange: (event: {target: {value: string}}) => {
                setValue(event.target.value);
            }
        }
     }),[value, classes]);  

    return searchBarProps;
};