React

[React] atom, selector를 사용한 minutes, hours 변환기

winter17 2023. 8. 11. 21:28

◈ 사용자가 분을 입력하면 자동으로 시간으로 변환하거나 시간을 입력하면 분으로 변환하는 간단한 시간 변환기

 React Recoil을 사용하여 상태를 관리하고 컴포넌트 간의 상호작용을 처리하는 방법을 보여준다.

 

minutes → hours
hours → minutes

 

▶ atoms.tsx

  • minutesState: 시간을 분 단위로 나타내는 atom을 정의한다. 기본 값은 0이다.
  • hourSelector: 분을 시간으로 변환하는 Selector를 정의한다. 
  • get함수: minutesState의 값을 가져와 분을 시간으로 변화하여 반환한다.
  • set함수: 입력된 시간을 분으로 변환하여 minutesState를 업데이트한다.
// atoms.tsx
import { atom, selector } from 'recoil'

export const minutesState = atom({
  key: 'minutes',
  default: 0,
})

export const hourSelector = selector<number>({
  key: 'hours',
  get: ({ get }) => {
    const minutes = get(minutesState)
    return minutes / 60
  },
  set: ({ set }, newValue) => {
    const minutes = Number(newValue) * 60
    set(minutesState, minutes)
  },
})

 

▶ App.tsx

  • minutes, setMinutes: 'minutesState' atom과 연결된 값과 상태 업데이트 함수를 가져온다.
  • hours, setHours: 'hoursSelector' Selector와 연결된 값과 상태 업데이트 함수를 가져온다.
  • onMinutesChange: 분 입력 필드의 변경 이벤트 핸들러이다. 입력된 값을 숫자로 변환하여 setMinutes를 호출하여 상태를 업데이트한다.
  • onHoursChange: 시간 입력 필드의 변경 이벤트 핸들러이다. 입력된 값을 숫자로 변환하여 setHours를 호출하여 상태를 업데이트한다.
  • 렌더링 부분에서는 두 개의 입력 필드를 생성하고, 입력된 값과 변경 이벤트 핸들러를 연결하여 사용자가 분과 시간을 입력하고 변환할 수 있도록 한다.
// App.tsx
import React from 'react'
import { useRecoilState } from 'recoil'
import { hourSelector, minutesState } from './atoms'

function App() {
  const [minutes, setMinutes] = useRecoilState(minutesState)
  const [hours, setHours] = useRecoilState(hourSelector)
  const onMinutesChange = (event: React.FormEvent<HTMLInputElement>) => {
    // 문자열을 숫자로 변환 +
    setMinutes(+event.currentTarget.value)
  }
  const onHoursChange = (event: React.FormEvent<HTMLInputElement>) => {
    setHours(+event.currentTarget.value)
  }
  return (
    <div>
      <input
        value={minutes}
        onChange={onMinutesChange}
        type="number"
        placeholder="Mintues"
      />
      <input
        value={hours}
        onChange={onHoursChange}
        type="number"
        placeholder="Hours"
      />
    </div>
  )
}

export default App