88

I've recently started learning React Native. Currently, I'm working on altering the TextInput style when an error occurs.

How could I refine my code to make it look more polished?


<TextInput style={ (touched && invalid) ? {
    height: 40,
    backgroundColor: 'white',
    borderRadius: 5,
    padding: 10,
    borderWidth: 2,
    borderColor: 'red'
  } : {
    height: 40,
    backgroundColor: 'white',
    borderRadius: 5,
    padding: 10
  }
} />

0xe1λ7r
  • 1,957
  • 22
  • 31
Kelvin
  • 2,218
  • 4
  • 22
  • 41

4 Answers4

237

Use StyleSheet.create to do style composition like this,

make styles for text, valid text, and invalid text.

const styles = StyleSheet.create({
    text: {
        height: 40, backgroundColor: 'white', borderRadius: 5, padding: 10, 
    },
    textvalid: {
        borderWidth: 2,
    },
    textinvalid: {
        borderColor: 'red',
    },
});

and then group them together with an array of styles.

<TextInput
    style={[styles.text, touched && invalid ? styles.textinvalid : styles.textvalid]}
</TextInput>

For array styles, the latter ones will merge into the former one, with overwrite rule for the same keys.

Val
  • 21,938
  • 10
  • 68
  • 86
17

Update your code as following:

<TextInput style={getTextStyle(this.state.touched, this.state.invalid)}></TextInput>

Then outside your class component, write:

getTextStyle(touched, invalid) {
 if(touched && invalid) {
  return {
    height: 40, backgroundColor: 'white', borderRadius: 5, padding: 10, borderWidth: 2, borderColor: 'red'
  }
 } else {
   return {
      height: 40, backgroundColor: 'white', borderRadius: 5, padding: 10
   }
 }
}
Rohan Kangale
  • 931
  • 4
  • 11
  • 29
6

There are two ways, by inline or calling a function:

1)

const styles = StyleSheet.create({
    green: {
        borderColor: 'green',
    },
    red: {
        borderColor: 'red',
    },
    
});

<TextInput style={[styles.otpBox, this.state.stateName ?
    styles.green :
    styles.red ]} />
getstyle(val) {
    if (val) {
        return { borderColor: 'red' };
    }
    else {
        return { borderColor: 'green' };
    }
}

<TextInput style={[styles.otpBox, this.getstyle(this.state.showValidatePOtp)]} />
Christos Lytras
  • 36,310
  • 4
  • 80
  • 113
Pravin Ghorle
  • 606
  • 7
  • 7
0

To make your code more readable and less repetitive, you can extract the common styles into a separate object and conditionally apply the specific styles for the error case. Here's an example:

const inputStyles = {
  height: 40,
  backgroundColor: 'white',
  borderRadius: 5,
  padding: 10,
};

const errorInputStyles = {
  ...inputStyles,
  borderWidth: 2,
  borderColor: 'red',
};

// Inside your component's render method
<TextInput
  style={touched && invalid ? errorInputStyles : inputStyles}
/>

In this code, I have defined two objects: inputStyles for the default input styling, and errorInputStyles which includes the additional styles for the error case. Use the spread operator (...) to merge the common styles with the error-specific styles.

Now, you can simply conditionally apply the styles based on the touched and invalid flags. If both are true, the errorInputStyles will be used, otherwise, the inputStyles will be applied. This approach makes the code cleaner and avoids duplication.

INDRA
  • 11
  • 3
  • This does not provide an answer to the question. Once you have sufficient [reputation](https://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](https://stackoverflow.com/help/privileges/comment); instead, [provide answers that don't require clarification from the asker](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). - [From Review](/review/late-answers/34477755) – 0xe1λ7r Jun 06 '23 at 04:55