在我清理一个庞大的react render语句的过程中,我一直在将一些东西分解成辅助函数。下面是辅助函数的一部分:
// This looks ugly
return (
<>
{label}
{getDropdown(
daysOfWeek,
handleDaysOfWeekChange,
daysOfWeekLabel,
options.dayOfWeek,
isMultiSelectEnabled
)}
</>
);
getDropdown函数的细节并不重要。Label是一个react组件(并且被定义为一个变量,因为它也在其他地方使用),getDropdown返回一个react组件。
出于某种原因,这看起来很丑,我们从一个react.fragment开始,这样我们就可以有多个javascript代码片段,但反过来每个javascript代码片段要么是一个等于react组件的变量,要么是一个在运行时计算到react组件的函数。所以我们真的是从react范式到javascript范式然后再回到react。
我想要这样的东西,这是所有javascript范例:
// invalid code!
return React.fillFragment(
label,
getDropdown(
daysOfMonth,
handleDaysOfMonthChange,
daysOfMonthLabel,
options.dayOfMonth,
isMultiSelectEnabled
),
);
返回一个数组只会给出键错误,我们不希望重载它,因为在其他地方,我们希望返回一个没有片段的数组。
我能想到的下一个最佳解决方案是简单地将这两个组件视为实际组件,这将是全反应范式:
// Works, but still feels verbose
return (
<>
<Label/>
<GetDropDown
value={daysOfMonth}
onChange={handleDaysOfMonthChange}
defaultLabel={daysOfMonthLabel}
listOptions={options.dayOfMonth}
isMultiSelect={isMultiSelectEnabled}
/>
</>
);
这确实可以工作,但是感觉有点过分,并且对于几个一次性使用的函数来说不是最简洁的。(例如label仅在此处和另一个位置使用)
我在想是不是有什么东西是我一直没能找到的,或者这里有一个我从未遇到过的小技巧?也许我太挑剔了
你最后的片段对我来说最好看。
如果getDropdown
返回一个React组件,那么它最好是一个React组件。
如果你不喜欢<></>
片段语法,你可以用<Fragment></Fragment>
来代替。
如果你根本不想要片段,你要么必须将你的组件Label
和GetDropDown
内联到它们的父组件中。或者把Label
放到GetDropDown
中(顺便说一下,GetDropDown
应该改名为Dropdown
)。
我不知道GetDropDown
和Label
的内容,但如果没有比select
和label
更多的内容,你可能不想创建React组件。
如果你有自定义样式应用于label
和select
元素,你可以添加一个全局样式表,或者-首选的解决方案-使用css-in-js库,如styled-components
:
// Label is a component, with the custom style you define here.
const Label = styled.label`
color: grey;
`;
添加这样的小组件,性能成本可以忽略不计。