[리팩토링] price input값 format 기능

1. 1000단위 콤마 찍기

seriesForm의 가격 입력 input의 값을 1000단위로 ','가 찍히도록 포맷팅되는 기능을 구현했다
1000단위로 ,를 찍으려면 뒤에서부터 숫자를 3개씩 세면서 ,를 찍어야한다
onChange가 될 때마다 input값을 가져와서 조건에 맞게 조작한 후 리턴해준다

  • input값을 받아 포맷해주는 함수 구현
    • 배열로 변환
    • 뒤집음
    • 요소들을 하나씩 순회하면서 3배수에 해당하는 index를 가졌다면 ','를 추가, 아니라면 그대로 리턴해 새로운 배열 생성 (4배수 번째 요소에 ,를 찍어야하는데 index는 0으로 시작하므로)
    • 뒤집어서 원래대로 만든 후
    • 문자열로 변환
// SeriesForm.jsx

export const formatPrice = input => {
  const formatedValue = input
    .split('')
    .reverse()
    .map((str, index) => (index > 0 && index % 3 === 0 ? `${str},` : str))
    .reverse()
    .join('');
  return formatedValue;
};
  • input value값에 함수를 적용해서 넣어줌
// SeriesForm.jsx

  <PayInput
    width="50%"
    type="text"
    value={formatPrice(values.price)}
    name="price"
    onChange={handleChange}
    min={0}
    disabled={edit}
  />
  • input값을 가져와 상태에 넣어줄 때 문자열과 맨 앞의 0을 제거해줌 (value값에 넣어줄 때 포맷팅 해야하므로)
  const handleChange = e => {
    const { name, value } = e.target;

    if (name === 'price') {
      const filteredValue = value.replace(/[^0-9]/g, '').replace(/(^0+)/g, '');
      setValues({ ...values, [name]: filteredValue });
      return;
    }

    setValues({ ...values, [name]: value });
  };

2. 한글 형식으로 포맷

구현 시도1

const changeNumberToText = value => {
  switch (value) {
    case '1':
      return '일';
    case '2':
      return '이';
    case '3':
      return '삼';
    case '4':
      return '사';
    case '5':
      return '오';
    case '6':
      return '육';
    case '7':
      return '칠';
    case '8':
      return '팔';
    case '9':
      return '구';
    default:
      return '';
  }
};

export const formatPriceToText = input => {
  const formatedValue = input
    .split('')
    .reverse()
    .map((str, index) => {
      const formattedValue = changeNumberToText(str);

      if (str === '0') {
        return '';
      }

      switch (index % 4) {
        case 1:
          return `${formattedValue}`;
        case 2:
          return `${formattedValue}`;
        case 3:
          return `${formattedValue}`;
        case 0:
          return index === 0 ? formattedValue : `${formattedValue}`;
        default:
          return formattedValue;
      }
    })
    .reverse()
    .join('');

  return formatedValue;
};

문제점

천 단위가 넘어 갔을 때 '만'이 안 붙는다

해결책

  • 천 단위가 넘어가면 '만'이 추가로 붙어야한다
  • 숫자의 뒤에서부터 4개를 끊어 천단위 이하의 값으로, 5번째~마지막 숫자까지 끊어 만단위 이상의 값으로 구분한 뒤에 각각 단위를 적용해준다 (자릿수에 따라 각 숫자들에 십, 백, 천의 단위를 붙여주는 것)
  • 단위가 적용된 만단위 이상 값과 천단위 이하 값을 서로 합쳐주어 리턴하는데, 만단위 이상 값에는 합치기 전에 추가로 '만'을 붙여준다
const addNumberUnit = (str, index) => {
  const formattedValue = changeNumberToText(str);
  if (str === '0') {
    return '';
  }
  switch (index % 4) {
    case 1:
      return `${formattedValue}`;
    case 2:
      return `${formattedValue}`;
    case 3:
      return `${formattedValue}`;
    default:
      return formattedValue;
  }
};

export const formatPriceToText = value => {
  const reversedValueArr = value.split('').reverse();

  const thousandUnitValue = reversedValueArr
    .slice(0, 4)
    .map((str, index) => addNumberUnit(str, index))
    .reverse()
    .join('');

  const tenThousandUnitValue =
    value.length <= 4
      ? ''
      : reversedValueArr
          .slice(4)
          .map((str, index) => addNumberUnit(str, index))
          .reverse()
          .join('')
          .concat('만');

  return tenThousandUnitValue + thousandUnitValue;
};

좋은 웹페이지 즐겨찾기