0

I have three same input fields that are masked to have phone format text. All input fields are exactly the same(Phone input field).now I have three states, with three handlePhoneNumber methods. This is not a good practice since all these fields are exactly the same basically.

The UI library I used is Material-UI and i used React-Text-Mask library for my mask component.

What I have so far:

this.state = {
    textmask: "(   )    -    ",
    textmask2: "(   )    -    ",
    textmask3: "(   )    -    ",
}

RenderTextMask(props){
    const { inputRef, ...other } = props;
    return (
      <MaskedInput
        {...other}
        ref={inputRef}
        mask={['(', /[1-9]/, /\d/, /\d/, ')', ' ', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/]}
        guide={true}
        showMask
      />
    );
}

My OutlienInput component(from material-UI), looks like this:

        <div>
            <FormLabel>Phone</FormLabel>
            <div>
                <OutlinedInput
                    value={this.state.textmask}
                    onChange={this.handlePhoneNumber}
                    inputComponent={this.RenderTextMask}
                    labelWidth={200}
                />
            </div>
        </div>
        <div>
            <FormLabel>Phone</FormLabel>
            <div>
                <OutlinedInput
                    value={this.state.textmask2}
                    onChange={this.handlePhoneNumber2}
                    inputComponent={this.RenderTextMask}
                    labelWidth={200}
                />
            </div>
        </div>
        <div>
            <FormLabel>Phone</FormLabel>
            <div>
                <OutlinedInput
                    value={this.state.textmask3}
                    onChange={this.handlePhoneNumber3}
                    inputComponent={this.RenderTextMask}
                    labelWidth={200}
                />
            </div>
        </div>

What the problem is: So far I need one state and one handle method for every phone field that I have. As you can see, as the app grows, the code is not really maintainable.

What I want to achieve: I want to have one state and one handle method that handles all three fields(possibly more fields in the future). Or something better than what I currently have. So in the future, if I have to add more fields, i don't have to modify state and add new method every time.

What I have tried so far I tried to have array testmask as state. The problem is that since I used react-text-mask as my mask library. it only accepts String. If I change "textmask" into array of strings, it will prompts error.

1 Answer 1

1

With a little guess, I would say that array is natural approach. There is just part of code, and I might be wrong.

IMO, you could do this:

this.state = {
    textmasks: ["(   )    -    ", "(   )    -    ", "(   )    -    "]
}

as you mentioned already. Now, in your render method, something like this:

const phoneInputs = [];
for (let i = 0; i < 3; i++) {
       phoneInputs.push(<div key={i}>
            <FormLabel>Phone</FormLabel>
            <div>
                <OutlinedInput
                    value={this.state.textmasks[i]}
                    onChange={this.handlePhoneNumber.bind(this, i)}
                    inputComponent={this.RenderTextMask}
                    labelWidth={200}
                />
            </div>
        </div>);
}

So, for this to work, you use this.state.textmasks[i] (input index) to catch appropriate mask. Also, to method this.handlePhoneNumber, you are binding index "i".

I wrote "this.state.textmasks[i]" and "this.handlePhoneNumber.bind(this, i)", just because I assumed that your implementation depends on phone number input index (not only to store to appropriate place, but to do some additional logic also).

If you will only use one text mask and only store list of phone numbers (I assume in handlePhoneNumber method), then you most likely should have:

const textMask = "(   )    -    ";
this.state = {
    phoneNumbers: []
};

This way, textMask wouldn't even be state/index dependent (what most likely is your business case) and phoneNumbers would be handled in onChange trigger (handlePhoneNumber method) which takes index as first parameter, so it can update appropriate phoneNumbers index.

Sign up to request clarification or add additional context in comments.

1 Comment

Yeah i figured that out right after I posted this. I am using the same method that you suggested. Thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.