React animationを試す
ReactでCSS animationを駆使する定番の方法である react-transition-groupを用いてTODO applicationを作ってみました。
React에서 CSS animation을 구사하는 방식인 react-transition-group를 사용해서 TODO application을 연습용으로 만들어 보았습니다.
import { useState, createRef } from 'react' import { TransitionGroup, CSSTransition } from 'react-transition-group' let globalId = 1 const InitData = [ [globalId++, 'todo job 1', createRef()], [globalId++, 'todo job 2', createRef()], [globalId++, 'todo job 3', createRef()], ] as [number, string, any][] export default function TodoList() { const [state, setState] = useState(InitData) const handleAdd = () => { const a = prompt('Enter some text') if (a === null) return const newItems = state.concat([ [globalId++, a, createRef()], ]) setState(newItems) } const handleReset = () => { setState(InitData) } const handleRemove = (i: number) => { let newItems = state.slice() newItems.splice(i, 1) setState(newItems) } const items = state.map(([id, item, nodeRef], i) => ( <CSSTransition key={id} nodeRef={nodeRef} timeout={500} classNames="item" > <li ref={nodeRef} onClick={() => handleRemove(i)}> {item} </li> </CSSTransition> )) return ( <> <style> {` .item-enter { opacity: 0; } .item-enter-active { opacity: 1; transition: opacity 500ms ease-in; } .item-exit { opacity: 1; } .item-exit-active { opacity: 0; transition: opacity 500ms ease-in; } `} </style> <section className="text-sm"> <p>This application is a simple TODO application demonstrating animation of React and Tailwind.</p> <p>このアプリは Reactでanimationをデモする例のtodo applicationです。cssはTailwindを用いています。</p> <p>React에서 animation을 시범해 보는 간단한 todo application입니다. css는 Tailwind를 사용하고 있습니다.</p> </section> <div className="flex justify-center"> <div className="inline-block"> <div className="text-center mt-2"> <button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded" onClick={handleAdd}>Add Item</button> <button className="ml-2 bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded" onClick={handleReset}>Reset</button> </div> <TransitionGroup className="mt-4 py-2 px-1 divide-y-2 list-decimal bg-slate-100 rounded-md min-w-[350px] list-inside" component="ol"> {items} </TransitionGroup> </div> </div> </> ) }