Реагируйте: Сохраните несколько похожих полей ввода в одном состоянии - PullRequest
0 голосов
/ 13 декабря 2018

У меня три одинаковых поля ввода, которые замаскированы под текстовый формат телефона.Все поля ввода одинаковы (поле ввода телефона). Теперь у меня есть три состояния с тремя handlePhoneNumber методами.Это не очень хорошая практика, так как все эти поля в основном одинаковы.

Я использовал библиотеку пользовательского интерфейса Material-UI, и я использовал React-Text-Mask библиотеку для моего компонента маски.

ЧтоУ меня так далеко:

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
      />
    );
}

Мой компонент OutlienInput (из Material-UI) выглядит так:

        <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>

В чем проблема: ПокаМне нужно одно состояние и один метод обработки для каждого телефонного поля, которое у меня есть.Как вы можете видеть, по мере роста приложения код на самом деле не подлежит сопровождению.

Чего я хочу достичь: Я хочу иметь одно состояние и один метод-обработчик, который обрабатывает все три поля.(возможно, больше полей в будущем).Или что-то лучше, чем у меня сейчас.Так что в будущем, если мне нужно будет добавить больше полей, мне не придется каждый раз изменять состояние и добавлять новый метод.

То, что я пробовал до сих пор Я пытался получитьТестовая маска массива как состояние.Проблема в том, что, поскольку я использовал react-text-mask в качестве моей библиотеки масок.он принимает только строку.Если я заменю «textmask» на массив строк, появится сообщение об ошибке.

1 Ответ

0 голосов
/ 13 декабря 2018

С небольшой догадкой я бы сказал, что массив - это естественный подход.Есть только часть кода, и я могу ошибаться.

IMO, вы можете сделать это:

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

, как вы уже упоминали.Теперь, в вашем методе рендеринга, что-то вроде этого:

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>);
}

Итак, чтобы это работало, вы используете this.state.textmasks [i] (входной индекс), чтобы поймать соответствующую маску.Кроме того, для метода this.handlePhoneNumber вы привязываете индекс «i».

Я написал «this.state.textmasks [i]» и «this.handlePhoneNumber.bind (this, i)», просто потому, чтоЯ предположил, что ваша реализация зависит от индекса ввода номера телефона (не только для сохранения в соответствующем месте, но также для выполнения некоторой дополнительной логики).

Если вы будете использовать только одну текстовую маску и хранить только список телефонных номеров(Я полагаю, в методе handlePhoneNumber), скорее всего, вы должны иметь:

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

Таким образом, textMask даже не будет зависеть от состояния / индекса (что, скорее всего, соответствует вашему бизнес-случаю), а phoneNumbers будетобрабатывается в триггере onChange (метод handlePhoneNumber), который принимает индекс в качестве первого параметра, поэтому он может обновить соответствующий индекс phoneNumbers.

...