React : Immer & 함수형 업데이트
import React from ‘react’ import {useState , useRef, useCallback} from ‘react’
import produce from ‘immer’ function App() { const nextId = useRef(1); const inputname = useRef() const [ form , setForm ] = useState({ name:” , username:”}); const [ data , setData ] = useState({ array : [ ], uselessValue : null }) | |
const onChange = useCallback( (e) => { const {name , value} = e.target; setForm({ …form, [name] : [value] }) /* 또는 , immer 를 이용한 상태 업데이트 */ setForm( produce(form , draft => { draft[name] = value }) ) }, [form]) useCallback 으로 함수를 memoizaion 할 경우 반드시 의존성배열에 상태가변경될경우 업데이트 되어야할 상태변수를 나열해준다. 단, useCallback 에서 변경한 상태는 실제 상태에서 적용됨 | const onChange = useCallback( (e) => { const {name , value} = e.target; setForm ( e => { return { …e, [name] : [value] } }) /* 또는 , immer 를 이용한 함수형 업데이트 */ // produce(사본객체 => { 사본객체 활용 } setForm( produce(draft => { draft[name] = value; }) ) }, [ ]) [ 함수형 업데이트 ] 최초 1회 렌더링만 한다. |
const onSubmit = useCallback( (e) => { e.preventDefault() const info = { id : nextId.current , name : form.name, username : form.username } | |
setData({ array : data.array.concat(info) }); | setData(produce(data , draft => { draft.array.push(info); })) // produe(원본 , 사본 => { |
setForm({name : ” , username:”}) nextId.current = nextId.current + 1; inputname.current.focus(); }, [form , data] ); const removeItem = useCallback((id) => { setData( { array : data.array.filter(e =>e.id !== id) } ) },[data]); return( <div> <form onSubmit={onSubmit}> <input name=”username” placeholder=”아이디” ref={inputname} value={form.username} onChange={onChange}/> <input name=”name” placeholder=”이름” value={form.name} onChange={onChange} /> <button type=”submit”>등록하기</button> </form> <div> <ul> { data.array.length } { data.array.map( e => { return <li key={e.id} onClick={()=>removeItem(e.id)}> {e.id} / {e.name} {e.username} </li> }) } </ul> </div> </div> ) } export default App; |