I have created a date component (working GIF at the bottom).
There isn't a problem with the working of the code but rather the code I wrote seems messy and something hard for any other person to comprehend.
Note: Please look at the GIF below. Also, Ignore the styling
this is what I am doing. For the date Component in screen, I am creating refs and state like this
class OnBoarding extends PureComponent {
    constructor(props) {
        super(props)
        this.d1 = React.createRef()
        this.d2 = React.createRef()
        this.d3 = React.createRef()
        this.d4 = React.createRef()
        this.d5 = React.createRef()
        this.d6 = React.createRef()
        this.d7 = React.createRef()
        this.d8 = React.createRef()
    }
    state = {
        name: '',
        emailAddress: '',
        dob: '',
        male: null,
        female: null,
        keyboard: false,
        d1: null,
        d2: null,
        d3: null,
        d4: null,
        d5: null,
        d6: null,
        d7: null,
        d8: null
    }
dobHandler(number, flag) {
        const completeFlag = `d${flag}`
        this.setState({[completeFlag]: number})
        flag = flag + 1
        if (flag < 9 && number) {
            const nextFlag = `d${flag}`
            const textInputToFocus = this[nextFlag]
            textInputToFocus.current.focus()
        }
    }
And then rendering them like this
       <View style={styles.dob}>
                        <TextInput
                            ref={this.d1}
                            numberOfLines={1}
                            maxLength={1}
                            style={styles.textInputDob}
                            keyboardType="numeric"
                            placeholder="D"
                            onChangeText={number => this.dobHandler(number, 1)}
                        />
                        <TextInput
                            ref={this.d2}
                            numberOfLines={1}
                            maxLength={1}
                            style={styles.textInputDob}
                            keyboardType="numeric"
                            placeholder="D"
                            onChangeText={number => this.dobHandler(number, 2)}
                        />
                        <Text>/</Text>
                        <TextInput
                            ref={this.d3}
                            numberOfLines={1}
                            maxLength={1}
                            style={styles.textInputDob}
                            keyboardType="numeric"
                            placeholder="M"
                            onChangeText={number => this.dobHandler(number, 3)}
                        />
                        <TextInput
                            ref={this.d4}
                            numberOfLines={1}
                            maxLength={1}
                            style={styles.textInputDob}
                            keyboardType="numeric"
                            placeholder="M"
                            onChangeText={number => this.dobHandler(number, 4)}
                        />
                        <Text>/</Text>
                        <TextInput
                            ref={this.d5}
                            numberOfLines={1}
                            maxLength={1}
                            style={styles.textInputDob}
                            keyboardType="numeric"
                            placeholder="Y"
                            onChangeText={number => this.dobHandler(number, 5)}
                        />
                        <TextInput
                            ref={this.d6}
                            numberOfLines={1}
                            maxLength={1}
                            style={styles.textInputDob}
                            keyboardType="numeric"
                            placeholder="Y"
                            onChangeText={number => this.dobHandler(number, 6)}
                        />
                        <TextInput
                            ref={this.d7}
                            numberOfLines={1}
                            maxLength={1}
                            style={styles.textInputDob}
                            keyboardType="numeric"
                            placeholder="Y"
                            onChangeText={number => this.dobHandler(number, 7)}
                        />
                        <TextInput
                            ref={this.d8}
                            numberOfLines={1}
                            maxLength={1}
                            style={styles.textInputDob}
                            keyboardType="numeric"
                            placeholder="Y"
                            onChangeText={number => this.dobHandler(number, 8)}
                        />
                    </View>
The reason I have made so many ref is because the moment someone enters something in the current textInput, I want the focus to moved to the next one, which happens in dobHandler function.
Can someone help me in improving quality/optimizing and if this is the wrong way of doing it, then hint me on How to achieve this alternativekly

Among many ways, you can write this as,
const placeholders = [ 'D', 'D', 'M', 'M', 'Y', 'Y', 'Y', 'Y'];
class OnBoarding extends PureComponent {
  constructor(props) {
    super(props)
    this.refs = Array(8).fill(0).map(_ => React.createRef())
  }
  state = {
    name: '',
    emailAddress: '',
    male: null,
    female: null,
    keyboard: false,
    dob: Array(8).fill(null)
  }
  dobHandler(number, index) {
    const { dob } = this.state
    dob[index] = number;
    this.setState({ dob:  [ ...dob ]})
    const ref = this.refs[index + 1]
    if (number && ref && ref.current)
      ref.current.focus()
  }
  render() {
    <View style={styles.dob}>
      {this.refs.map((ref, i) => (
        <>
          <TextInput
            ref={ref}
            numberOfLines={1}
            maxLength={1}
            style={styles.textInputDob}
            keyboardType="numeric"
            placeholder={placeholders[i]}
            onChangeText={number => this.dobHandler(number, i)}
          />
         {(i == 1 || i == 3) && <Text>/</Text>}
       </>        
      ))}
    </View>
  }
}
Since you have a repetitive set, you can use arrays while conditionally inserting the slashes where needed based on index.
You can create a function to return a TextInput with ref, placeholder and num as parameters
renderTextInput(ref, placeholder, num) {
  return (
    <TextInput
      ref={ref}
      numberOfLines={1}
      maxLength={1}
      style={styles.textInputDob}
      keyboardType="numeric"
      placeholder={placeholder}
      onChangeText={number => this.dobHandler(number, num)}
    />
  )
}
Then call it inside the render method
return (
  <View style={styles.dob}>
    {renderTextInput(this.d1, "D", 1))}
    {renderTextInput(this.d2, "D", 2))}
    ...
    ...
  </View>
);
                        Have you considered using Material UI datepicker, and store your DOB as a Date object instead?
If you are using Material v4.x, simply follow the demo. Otherwise, you need to first install material-ui-pickers package. Then,
import { DatePicker, KeyboardDatePicker } from "material-ui-pickers"; // if and only if using Material v3.x
You can then replace your previous implementation with this:
  <KeyboardDatePicker
    autoOk
    variant="inline"
    inputVariant="outlined"
    label="Your DOB"
    format="MM/dd/yyyy"
    placeholder="DD/MM/YYYY" /* use placeholder to guide how your user should enter the date format, in this case, I simply followed your GIF demo */
    value="" /* use a default value or leave it empty */
    InputLabelProps= {{ /* customise style of your label */ }}
    InputProps= {{ /* customise style of how your input should look like */ }}
    InputAdornmentProps={{ position: "start" }}
    onChange={date => handleDateChange(date)}
  />
Your dobHandler will no longer be needed. You will simply update your DOB state value or save your DOB using handleDateChange().
handleDateChange(date){
  /* do something whenever a new date is entered */
}
This should address the followings without your existing dobHandler function, and the long TextField per integer.
I want the focus to moved to the next one, which happens in dobHandler function
Answer: This will be handled by Material UI's datepicker, refer to demo here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With