0

嗨,我有 2 个下拉菜单,但为此我正在管理 2 个状态。请帮我减少重复的代码。假设,如果我想要 10 个下拉菜单,那么我的状态数和相同的方法会重复相同。如果有办法重构代码以减少状态和方法的数量会更好。

注意:我有一个基于类的组件

this.state = {
            isOpen: false,
            selected: null,
            isDisabled: false,
            isOpen1: false,
            selected1: null,
            isDisabled1: false,
           
            isOpen2: false,
            selected2: null,
            isDisabled2: false, }

内部构造函数



  this.options = [
            <SelectOption key={0} value={hourTxt} isPlaceholder />,
            <SelectOption key={1} value={weekTxt} />,
            <SelectOption key={2} value={dayTxt} />,
            <SelectOption key={3} value={neverTxt} />, 
          ];

          this.options1 = [
            <SelectOption key={0} value={hourTxt} />,
            <SelectOption key={1} value={weekTxt} />,
            <SelectOption key={2} value={dayTxt} isPlaceholder />,
            <SelectOption key={3} value={neverTxt} />, 
          ];

     
      this.onToggle = (isOpen) => {
        this.setState({
          isOpen
        });
      };

      this.onToggle1 = isOpen1 => {
        this.setState({
          isOpen1
        });
      };

this.onSelect = (event, selection, isPlaceholder) => {
        if (isPlaceholder){

         this.clearSelection();
        }
        else {
          this.setState({
            selected: selection,
            isOpen: false
          },() => { this.postSelectData()

          });
        }
      };

      this.onSelect1 = (event, selection, isPlaceholder) => {
        if (isPlaceholder) this.clearSelection1();
        else {
          this.setState({
            selected1: selection,
            isOpen1: false
          },() => { this.postSelectData()

          });
        }
      };

 this.clearSelection = () => {
        this.setState({
          selected: null,
          isOpen: false
          },() => { this.postSelectData()
          });
       
      };

      this.clearSelection1 = () => {
        this.setState({
          selected1: null,
          isOpen1: false
        },() => { this.postSelectData()
        });
     
    };

在渲染()下

const {isOpen, selected,isOpen1, selected1} = this.state

在 return() 下


 <Select
        
          variant={SelectVariant.single}
          onToggle={this.onToggle}
          onSelect={this.onSelect}
          selections={selected}
          isOpen={isOpen}
         
          
        >
         {this.options}
         
        </Select>
 <Select
              variant={SelectVariant.single}
              onToggle={this.onToggle1}
              onSelect={this.onSelect1}
              selections={selected1}
              isOpen={isOpen1}
              
            >
              {this.options1}
            </Select>

4

1 回答 1

0

为避免代码重复,您可以将要复制到组件中的逻辑抽象化,然后创建该组件的多个实例。有多少可以重用或不能重用取决于手头的具体要求。

在您的情况下,您可以创建一个Dropdown包含所有静态部分、通用逻辑和相关处理函数的组件。反过来,每个实例特定的所有内容都必须由父组件管理并传递给下拉组件(通常作为道具)。

下面的代码片段可能会帮助您实现您想要的。它是一个基本的下拉组件,提供启用/禁用切换(一般逻辑)并包含所有静态部分(例如<select>,默认值)。父组件 ( )通过将细节(标签、选项、onChange 操作)作为道具传递给组件来App呈现组件的多个实例。Dropdown通过 onChange 操作,父组件中的状态将更新为在任一下拉列表中最后选择的值。

const { useState } = React;

const Dropdown = (props) => {
  const [disabled, setDisabled] = useState(false);
  return (
    <div>
      {props.label}
      <button onClick={() => setDisabled(!disabled)}>{disabled ? "enable" : "disable"}</button>
      <br />
      <select onChange={(e) => props.action(e.target.value)} disabled={disabled}>
        <option value="default">I am a default value</option>
        {props.options.map((o) => (
          <option value={o.value}>{o.label}</option>
        ))}
      </select>
    </div>
  );
};
const App = () => {
  const dropdown1 = {
    label: "My first Dropdown",
    options: [
      { value: "value1", label: "entry1" },
      { value: "value2", label: "entry2" },
      { value: "value3", label: "entry3" },
    ],
    action: (val) => setLastSelectedValue(val),
  };

  const dropdown2 = {
    label: "My second Dropdown",
    options: [
      { value: "value4", label: "entry4" },
      { value: "value5", label: "entry5" },
      { value: "value6", label: "entry6" },
    ],
    action: (val) => setLastSelectedValue(val),
  };

  const [lastSelectedValue, setLastSelectedValue] = useState();

  return (
    <div>
      <Dropdown {...dropdown1} />
      <Dropdown {...dropdown2} />
      {lastSelectedValue && <p>Last selected value: {lastSelectedValue}</p>}
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>

于 2021-07-29T16:57:16.677 回答