Is splitting the render method of a component into functions considered an anti-pattern?
I mean, I now that we can pefectly split it into more components if the JSX grows too big...
But, what about the following example:
/**
* 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>
);
}
Should I avoid splitting the code here? As you can see... I am using custom components for the most "atomic" parts... and two inner helper methods to render them with the corresponding layout tweaks.
Pattern or anti-pattern?
CodePudding user response:
No, abstracting the UI into different JSX components is not an anti-pattern. It is the opposite. It is recommended.
However, I would consider the way you are doing it an anti-pattern. You should not render a JSX functional component by calling it inline as a plain JS function. It works but it is unnecessary.
Instead of writing
<View style={globalStyles.flexHorizontallyCenteredContainer}>
{renderInputs()}
{renderContinueButton()}
</View>
You can directly create the JSX component as a child of the View
as follows.
<View style={globalStyles.flexHorizontallyCenteredContainer}>
<renderInputs />
<renderContinueButton />
</View>
Since both of them are JSX components. In this case, it is generally expected that a JSX component starts with a capital letter and isn't named using a verb. Thus, I would recommend naming them as follows.
const Inputs = () => {
return (...)
}
const ContinueButton = () => {
return (...)
}
While it is fine to define components inside a another component and then create it inside the render function of the main component, it often is advised to create new files. Thus, Inputs
and ContinueButton
would be placed inside a new file, e.g. Inputs.js
and ContinueButton.js
. You can export them as usual and import them. This makes it possible to reuse components in different places.