ReactJS Patternfly 减少下拉菜单的重复代码
ReactJS Patternfly reduce duplicated code for dropdowns
您好,我有 2 个下拉菜单,但为此我正在使用它管理 2 个状态。请帮助我减少重复代码。假设,如果我想有 10 个下拉列表,那么我的状态数和相同的方法会重复相同的。如果有办法重构代码以减少状态和方法的数量会更好。
注意:我有一个基于 class 的组件
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>
为避免代码重复,您可以将重复的逻辑抽象为一个组件,然后创建该组件的多个实例。可以重复使用多少,不能重复使用多少取决于手头的具体要求。
对于您的情况,您可以创建一个 Dropdown
组件,其中包含所有静态部分、通用逻辑和相关的处理函数。
反过来,每个实例特定的所有内容都必须由父组件管理并传递给下拉组件(通常作为道具)。
下面的代码片段可能会帮助您实现您的目标。它是一个基本的下拉组件,提供 enabling/disabling 切换(通用逻辑)并包含所有静态部分(例如,<select>
,默认值)。父组件 (App
) 通过将细节(标签、选项、onChange 操作)作为道具传递给它来呈现 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>
您好,我有 2 个下拉菜单,但为此我正在使用它管理 2 个状态。请帮助我减少重复代码。假设,如果我想有 10 个下拉列表,那么我的状态数和相同的方法会重复相同的。如果有办法重构代码以减少状态和方法的数量会更好。
注意:我有一个基于 class 的组件
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>
为避免代码重复,您可以将重复的逻辑抽象为一个组件,然后创建该组件的多个实例。可以重复使用多少,不能重复使用多少取决于手头的具体要求。
对于您的情况,您可以创建一个 Dropdown
组件,其中包含所有静态部分、通用逻辑和相关的处理函数。
反过来,每个实例特定的所有内容都必须由父组件管理并传递给下拉组件(通常作为道具)。
下面的代码片段可能会帮助您实现您的目标。它是一个基本的下拉组件,提供 enabling/disabling 切换(通用逻辑)并包含所有静态部分(例如,<select>
,默认值)。父组件 (App
) 通过将细节(标签、选项、onChange 操作)作为道具传递给它来呈现 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>