Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React anti-patterns - Splitting the render method into functions

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?

like image 597
Victorio Molina Avatar asked Dec 07 '25 11:12

Victorio Molina


1 Answers

No, abstracting the UI into different JSX components is not an anti-pattern. It is the opposite. It is recommended.

Sometimes, it might might more sense to create new JSX components instead. Thus, instead of writing

<View style={globalStyles.flexHorizontallyCenteredContainer}>
      {renderInputs()}
      {renderContinueButton()}
</View>

You could 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.

like image 80
David Scholz Avatar answered Dec 08 '25 23:12

David Scholz