How to align label and input in react native?

Olivier MATROT picture Olivier MATROT · Dec 12, 2018 · Viewed 12.7k times · Source

I have to build a simple form where I have 3 labels and 3 TextInput. I want to have them on top of each other with a space between the rows.

I can't figure out the right way to do it properly.

My first attempt is to have a top View with flexDirection: 'row' then a first sub view for the labels, followed by a second sub view with the text inputs. These two views have flexDirection: "column" and justifyContent: "space between".

The views:

<View style={[InitWindowStyles.root]}>
        <View style={InitWindowStyles.textBoxAndInputBox}>
          <Text>User Name</Text>
          <Text>Password</Text>
        </View>
        <View style={InitWindowStyles.textBoxAndInputBox}>
          <TextInput
            autoCorrect={false}
            onChangeText={this.onUserNameChange}
            value={this.state.userName}
            style={{ backgroundColor: 'white', borderColor: 'black' }}
          />
          <TextInput
            autoCorrect={false}
            onChangeText={this.onPasswordChange}
            value={this.state.password}
            style={{ backgroundColor: 'white', borderColor: 'black' }}
            secureTextEntry={true}
          />
        <View>
      <View>

The Styles:

const InitWindowStyles = StyleSheet.create({

    root: {
        flex: 1,
        flexDirection: "row"
      },
    textBoxAndInputBox: {
        flex: 1, 
        flexDirection: "column",
        justifyContent: "space-between",

      }
})

The result is not that bad but not perfect.

enter image description here

The advantage that I see is that the first column is automatically sized to the largest label (not shown in the picture above), and the second column takes the available size. And it works in both portrait and landscape mode...

What is the right way to do it ?

Should I have a top view with flexDirection:"column" and sub views for each pair of label and text ?

In an Android Layout, I would have used a GridView to achieve what I want.

Answer

Niels Ladekarl picture Niels Ladekarl · Dec 13, 2018

If i understood correctly, you are trying to create a table structure with 3 rows and 2 columns?

This can be achieved by having a top view with flexDirection set to 'column' and child views for each row that has flexDirection set to 'row':

<View style={InitWindowStyles.root}>
  <View style={InitWindowStyles.rowContainer}>
    <Text style={InitWindowStyles.text}>User Name</Text>
    <TextInput
      autoCorrect={false}
      onChangeText={this.onUserNameChange}
      value={this.state.userName}
      style={InitWindowStyles.textInput}
    />
  </View>
  <View style={InitWindowStyles.rowContainer}>
    <Text style={InitWindowStyles.text}>Password</Text>
    <TextInput
      autoCorrect={false}
      onChangeText={this.onPasswordChange}
      value={this.state.password}
      style={InitWindowStyles.textInput}
      secureTextEntry={true}
    />
  </View>
  <View style={InitWindowStyles.rowContainer}>
    <Text style={InitWindowStyles.text}>Label 3</Text>
    <TextInput
      style={InitWindowStyles.textInput}
    />
  </View>
</View>

And the StyleSheet

const InitWindowStyles = StyleSheet.create({
  root: {
    flex: 1,
    flexDirection: "column",
  },
  rowContainer: {
    flex: 1, 
    flexDirection: "row",
    justifyContent: "space-between",
    alignItems: "center"
  },
  text: {
    flex: 1
  },
  textInput: {
    flex: 1,
    backgroundColor: 'white', 
    borderColor: 'black',
  }
})