React 反模式 - 将渲染方法拆分为函数
React anti-patterns - Splitting the render method into functions
将组件的渲染方法拆分为函数是否被视为反模式?
我的意思是,如果 JSX 变得太大,我现在可以完美地将它拆分成更多的组件...
但是,下面的例子呢:
/**
* Renders the text inputs of the form.
*
* @returns {React.ReactElement} The text inputs.
*/
const renderInputs = () => (
<View style={styles.inputsContainer}>
<UsernameInput
ref={usernameInputRef}
label={t(
"authentication.signUp.accountInformation.usernameInputLabel"
)}
returnKeyType="next"
onChange={handleOnTextInputChange}
onSubmitEditing={() => emailInputRef.current.focus()}
containerStyle={commonStyles.textInputContainer}
/>
<TextInput
ref={emailInputRef}
label={t("authentication.signUp.accountInformation.emailInputLabel")}
maxLength={MAX_EMAIL_LENGTH}
textContentType="emailAddress"
keyboardType="email-address"
returnKeyType="next"
icon={{
name: "email",
type: "material",
color: colors.scorpion,
}}
onChange={handleOnTextInputChange}
onSubmitEditing={() => passwordInputRef.current.focus()}
containerStyle={commonStyles.textInputContainer}
/>
<PasswordInput
ref={passwordInputRef}
label={t(
"authentication.signUp.accountInformation.passwordInputLabel"
)}
textContentType="newPassword"
returnKeyType="next"
onChange={handleOnTextInputChange}
onSubmitEditing={() => repeatPasswordInputRef.current.focus()}
containerStyle={commonStyles.textInputContainer}
/>
<PasswordInput
ref={repeatPasswordInputRef}
label={t(
"authentication.signUp.accountInformation.repeatPasswordInputLabel"
)}
textContentType="oneTimeCode"
returnKeyType="done"
blurOnSubmit
onChange={handleOnTextInputChange}
containerStyle={commonStyles.textInputContainer}
/>
</View>
);
/**
* Renders a button for continuing to the next screen.
*
* @returns {React.ReactElement} The *'continue'* button.
*/
const renderContinueButton = () => (
<Button
disabled={isContinueDisabled}
uppercase
mode="contained"
onPress={handleOnContinue}
style={styles.button}
labelStyle={globalStyles.buttonLabel}
>
{t("authentication.signUp.accountInformation.continueButton")}
</Button>
);
return (
<View style={globalStyles.flexHorizontallyCenteredContainer}>
{renderInputs()}
{renderContinueButton()}
</View>
);
}
我应该避免在这里拆分代码吗?如您所见...我正在为大多数“原子”部分使用自定义组件...以及两个内部辅助方法以通过相应的布局调整来呈现它们。
模式还是反模式?
不,将 UI 抽象为不同的 JSX 组件并不是 anti-pattern。恰恰相反。值得推荐。
有时,创建新的 JSX 组件可能更有意义。因此,而不是写
<View style={globalStyles.flexHorizontallyCenteredContainer}>
{renderInputs()}
{renderContinueButton()}
</View>
您可以直接创建 JSX 组件作为 View
的子组件,如下所示。
<View style={globalStyles.flexHorizontallyCenteredContainer}>
<renderInputs />
<renderContinueButton />
</View>
因为它们都是 JSX 组件。在这种情况下,通常期望 JSX 组件以大写字母开头并且不使用动词命名。因此,我建议将它们命名如下。
const Inputs = () => {
return (...)
}
const ContinueButton = () => {
return (...)
}
虽然可以在另一个组件中定义组件,然后在主组件的渲染函数中创建它,但通常建议创建新文件。因此,Inputs
和 ContinueButton
将被放置在一个新文件中,例如Inputs.js
和 ContinueButton.js
。您可以照常导出它们并导入它们。这使得在不同地方重用组件成为可能。
将组件的渲染方法拆分为函数是否被视为反模式?
我的意思是,如果 JSX 变得太大,我现在可以完美地将它拆分成更多的组件...
但是,下面的例子呢:
/**
* Renders the text inputs of the form.
*
* @returns {React.ReactElement} The text inputs.
*/
const renderInputs = () => (
<View style={styles.inputsContainer}>
<UsernameInput
ref={usernameInputRef}
label={t(
"authentication.signUp.accountInformation.usernameInputLabel"
)}
returnKeyType="next"
onChange={handleOnTextInputChange}
onSubmitEditing={() => emailInputRef.current.focus()}
containerStyle={commonStyles.textInputContainer}
/>
<TextInput
ref={emailInputRef}
label={t("authentication.signUp.accountInformation.emailInputLabel")}
maxLength={MAX_EMAIL_LENGTH}
textContentType="emailAddress"
keyboardType="email-address"
returnKeyType="next"
icon={{
name: "email",
type: "material",
color: colors.scorpion,
}}
onChange={handleOnTextInputChange}
onSubmitEditing={() => passwordInputRef.current.focus()}
containerStyle={commonStyles.textInputContainer}
/>
<PasswordInput
ref={passwordInputRef}
label={t(
"authentication.signUp.accountInformation.passwordInputLabel"
)}
textContentType="newPassword"
returnKeyType="next"
onChange={handleOnTextInputChange}
onSubmitEditing={() => repeatPasswordInputRef.current.focus()}
containerStyle={commonStyles.textInputContainer}
/>
<PasswordInput
ref={repeatPasswordInputRef}
label={t(
"authentication.signUp.accountInformation.repeatPasswordInputLabel"
)}
textContentType="oneTimeCode"
returnKeyType="done"
blurOnSubmit
onChange={handleOnTextInputChange}
containerStyle={commonStyles.textInputContainer}
/>
</View>
);
/**
* Renders a button for continuing to the next screen.
*
* @returns {React.ReactElement} The *'continue'* button.
*/
const renderContinueButton = () => (
<Button
disabled={isContinueDisabled}
uppercase
mode="contained"
onPress={handleOnContinue}
style={styles.button}
labelStyle={globalStyles.buttonLabel}
>
{t("authentication.signUp.accountInformation.continueButton")}
</Button>
);
return (
<View style={globalStyles.flexHorizontallyCenteredContainer}>
{renderInputs()}
{renderContinueButton()}
</View>
);
}
我应该避免在这里拆分代码吗?如您所见...我正在为大多数“原子”部分使用自定义组件...以及两个内部辅助方法以通过相应的布局调整来呈现它们。
模式还是反模式?
不,将 UI 抽象为不同的 JSX 组件并不是 anti-pattern。恰恰相反。值得推荐。
有时,创建新的 JSX 组件可能更有意义。因此,而不是写
<View style={globalStyles.flexHorizontallyCenteredContainer}>
{renderInputs()}
{renderContinueButton()}
</View>
您可以直接创建 JSX 组件作为 View
的子组件,如下所示。
<View style={globalStyles.flexHorizontallyCenteredContainer}>
<renderInputs />
<renderContinueButton />
</View>
因为它们都是 JSX 组件。在这种情况下,通常期望 JSX 组件以大写字母开头并且不使用动词命名。因此,我建议将它们命名如下。
const Inputs = () => {
return (...)
}
const ContinueButton = () => {
return (...)
}
虽然可以在另一个组件中定义组件,然后在主组件的渲染函数中创建它,但通常建议创建新文件。因此,Inputs
和 ContinueButton
将被放置在一个新文件中,例如Inputs.js
和 ContinueButton.js
。您可以照常导出它们并导入它们。这使得在不同地方重用组件成为可能。