08 Create

 

이번 장은 CRUD 중 생성 부분을 실습해 보는 장이다. 교재 내용과 비슷하게 나도 list를 하나 만들어서 CRUD를 해볼까 한다. 아래와 같이 코드를 좀 확장해 보았다.

function List(props) {
const ltag = props.list.map((item) => (
<li key={item.id}>{item.name}</li>
));
return (
<ul>
{ltag}
</ul>
);
}
function Action(props) {
if(props.type == 'ADD') {
return (
<div>
<h2>Add</h2>
<input type='text' name='name' placeholder='name' />
<button onClick={
evt => {
const input = evt.target.parentElement.querySelector("input[name='name']");
const name = input.value;
props.callback(props.type, name);
input.value = '';
}}>OK</button>
</div>
);
}
else if(props.type == 'UPDATE') {
return (
<div>
<h2>Update</h2>
</div>
);
}
else if(props.type == 'DELETE') {
return (
<div>
<h2>Delete</h2>
</div>
);
}
}
function App() {
const [isClicked, setIsClicked] = useState(false);
const handler = ()=>{alert(`I'm a handler. more clicked: ${isClicked}`); setIsClicked(true);};
const [list, _] = useState([{id:1, name:'list1'}, {id:2, name:'list2'}, {id:3, name:'list3'}]);
const [listVer, setListVer] = useState(0);
const [actionType, setActionType] = useState('NONE');
const actionCallback = (type, ret) => {
if(type == 'ADD') {
list.push({id:list.length+1, name:ret});
setListVer(listVer+1);
}
};
return (
<div>
<Header Other='Custom' onClickHandler={handler} />
<List list={list} />
<p>
<ul style={{listStyle:'none'}}>
<li onClick={() => setActionType('ADD')}>Add</li>
<li onClick={() => setActionType('UPDATE')}>Update</li>
<li onClick={() => setActionType('DELETE')}>Delete</li>
</ul>
<Action type={actionType} callback={actionCallback}/>
</p>
</div>
);
}

간단히 설명해 보면 단순히 배열 내용을 표시하는 List라는 컴포넌트를 만들었고, List에 대한 CUD를 처리하기 위해 Action이라는 컴포넌트를 만들었다. App 컴포넌트는 has-a 관계로써 이들을 컴포지션하는 역할을 한다. 실행해 보면 아래 그림처럼 나온다.

Add를 누르면

여기에 practice1이라는 텍스트를 입력하고 OK를 누르면

교재 내용과 골자는 동일하다.

 


교재와 다른 점은 리스트 아이템 추가 시 리렌더링 하는 방식이다. 교재에서는 화면 갱신을 위해 아래와 같은 작업을 한다.

const [list, setList] = useState([{id:1, name:'list1'}, {id:2, name:'list2'}, {id:3, name:'list3'}]);
...
...
...
const newItem = {id:4, name:'practice1'};
const newList = [...list];
newList.push(newItem);
setList(newList);
...
...

list 객체를 deep copy하고 있다. 원소들까지 깊은 복사를 하는지 레퍼런스로 처리하는지는 모르겠으나 어쨌든 낭비적인 요소다.

그래서, 본인은 아래와 같이 list의 버전 변수를 이용하여 화면 갱신 이벤트가 발생할 수 있도록 하였다.

const [list, _] = useState([{id:1, name:'list1'}, {id:2, name:'list2'}, {id:3, name:'list3'}]);
const [listVer, setListVer] = useState(0);
...
...
const newItem = {id:4, name:'practice1'};
list.push(newItem);
setListVer(listVer+1);
...
...

교재의 코드와 다른 점이 느껴지는가? list의 크기가 커지면 커질수록 성능 차이는 명확할 것이다.

아무래도 나는 서버 개발자이다 보니 이런 부분에 민감한 것 같다.

 

Posted by JMAN