首页 > 解决方案 > 我将 JSS 样式放在一个自定义的 React 挂钩中。这很糟糕吗?

问题描述

我一直在努力寻找一种方法来制作一个可靠的可重用 SearchBar 组件。我试图为它制作一个组件。然而,这个组件不能保持自己的状态。这意味着您将有两个导入来使用此搜索栏。像这样的东西:

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>

}

这很容易,但我的大脑开始运转......我在互联网上找到了一个“useInput”自定义挂钩,它使用传播语法将一些道具传递给“输入”标签......我决定看看我能走多远这个。

事实证明,我们在项目中使用了JSS,这时候事情就变得有点荒谬了。这是我的钩子:

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...
    },
});

最简单的实现如下所示:

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

const Component = () => {

   const { bindSearchBar, value } = useSearchBar();

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

}

我需要一份清单,但我想你明白了。我有一种奇怪的感觉,觉得这有什么大问题。我很确定我现在会喜欢它,但 6 个月后我会恨自己。谁能告诉我这里可能出了什么问题或为什么这可能是不好的做法?还是您认为以这种方式使用钩子有点可行?

标签: javascriptreactjsreact-hooksjss

解决方案


在钩子中创建 jss 类没有错。useStyles 是一个钩子,自定义钩子的属性是使用其中的其他钩子。

除此之外,这里有一个性能提示。

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;
};


推荐阅读