• Home
  • About
    • lahuman photo

      lahuman

      열심히 사는 아저씨

    • Learn More
    • Facebook
    • LinkedIn
    • Github
  • Posts
    • All Posts
    • All Tags
  • Projects

react + material ui + typescript validation

23 May 2022

Reading time ~2 minutes

React Mui Validation

Typescript + React + Mui + Validation 코드 바로 가기

material ui 의 error와 helperText를 지원하는 공통 기능입니다.

Installation

React Mui Validation 패키지 설치를 할수 있습니다.

$ npm install react-mui-validation --save
# or
$ yarn add react-mui-validation

Functions

  • required : 필수값
  • min : 최소값
  • max : 최대값
  • same : 동일값
  • regex : 정규식

Usage

ViewModel

Rule을 가지고 있는 BaseModel을 상속받아 ViewModel을 구현 합니다.

아래는 ViewModel 예제입니다.

import {BaseModel, RegexAndMsg } from "react-mui-validation";

export class PaymentModel extends BaseModel {
   static required = ["cardName", "cardNumber", "expDate", "cvv"];

   static regex = {
    cardNumber: new RegexAndMsg(
      /(5[1-5]\d{14})|(4\d{12})(\d{3}?)|3[47]\d{13}|(6011\d{12})/i,
      "wrong card number"
    ),
    cvv: new RegexAndMsg(
      /^[0-9]{3,4}$/i,
      "Last three digits on signature strip"
    ),
  };

  cardName: string;
  cardNumber: string;
  expDate: string;
  cvv: string;

  constructor(data: Partial<PaymentModel>) {
    super();
    const { cardName, cardNumber, expDate, cvv } = data;
    this.cardName = cardName ?? "";
    this.cardNumber = cardNumber ?? "";
    this.expDate = expDate ?? "";
    this.cvv = cvv ?? "";
  }
}

Tsx

화면 코드 예제입니다. makeErrorProps 함수를 이용해서 입력값에 대한 검증 결과를 반영합니다.

import * as React from 'react';
import Typography from '@mui/material/Typography';
import Grid from '@mui/material/Grid';
import TextField from '@mui/material/TextField';
import FormControlLabel from '@mui/material/FormControlLabel';
import Checkbox from '@mui/material/Checkbox';
import { DataProps } from '../App';
import { PaymentModel } from './PaymentModel';
import { makeErrorProps } from 'react-mui-validation';

export default function PaymentForm(props: DataProps<PaymentModel>) {
  const {data, setData, errorState} = props;
  
  const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const { name, value, type } = e.target;
    if (type === 'number' && parseInt(value) < 0) {
      setData({
        ...data,
        [name]: 0,
      });
      return;
    }
    setData({
      ...data,
      [name]: value,
    });
  };
  return (
    <React.Fragment>
      <Typography variant="h6" gutterBottom>
        Payment method
      </Typography>
      <Grid container spacing={3}>
        <Grid item xs={12} md={6}>
          <TextField
            required
            id="cardName"
            name="cardName"
            label="Name on card"
            fullWidth
            autoComplete="cc-name"
            variant="standard"
            value={data.cardName}
            onChange={onChange}
            {...makeErrorProps(errorState, 'cardName')}
          />
        </Grid>
        <Grid item xs={12} md={6}>
          <TextField
            required
            id="cardNumber"
            name="cardNumber"
            label="Card number"
            fullWidth
            autoComplete="cc-number"
            variant="standard"
            value={data.cardNumber}
            onChange={onChange}
            {...makeErrorProps(errorState, 'cardNumber')}
          />
        </Grid>
        <Grid item xs={12} md={6}>
          <TextField
            required
            id="expDate"
            name="expDate"

            label="Expiry date"
            fullWidth
            autoComplete="cc-exp"
            variant="standard"
            value={data.expDate}
            onChange={onChange}
            {...makeErrorProps(errorState, 'expDate')}
          />
        </Grid>
        <Grid item xs={12} md={6}>
          <TextField
            required
            id="cvv"
            name="cvv"
            label="CVV"
            fullWidth
            autoComplete="cc-csc"
            variant="standard"
            value={data.cvv}
            onChange={onChange}
            {...makeErrorProps(errorState, 'cvv')}
          />
        </Grid>
        <Grid item xs={12}>
          <FormControlLabel
            control={<Checkbox color="secondary" name="saveCard" value="yes" />}
            label="Remember credit card details for next time"
          />
        </Grid>
      </Grid>
    </React.Fragment>
  );
}

Input validation call

아래 코드는 전체 코드 중 validation(rule, data)을 호출하는 코드 입니다.


const handleNext = () => {
  let result = {
    newErrorState: {},
    isValid: false
  }
  if(activeStep === 0){
    result = validation(AddressModel, addressData);
  }else if(activeStep === 1){
    result = validation(PaymentModel, paymentData);
  }

  setErrorState({
    ...errorState,
    ...result.newErrorState,
  });
  if (!result.isValid) {
    return;
  }
  setActiveStep(activeStep + 1);
};

전체 예제 코드

CodeSandbox

위의 예제는 Mui ckeckout template 를 기반으로 만들었습니다.

License

License

  • MIT license
  • Copyright 2022 © lahuman.


typescriptreactmui Share Tweet +1