BindModel 과 React Mix 비교
설명
리액트 폴더 구조
react-mix1/
├── componets/
│ ├── NoticeAdminPage.js
│ ├── NoticeForm.js
│ └── NoticeList.js
├── app.js
└── admin.html
NoticeAdminPage.js : React
이 코드는 비즈니스 로직과 발표의 핵심을 구현하는 코드입니다.
import React from 'https://esm.sh/react';
import NoticeList from './NoticeList.js';
import NoticeForm from './NoticeForm.js';
const { useState, useEffect } = React;
export default function NoticeAdminPage() {
const [notices, setNotices] = useState([]);
const [selectedNotice, setSelectedNotice] = useState(null);
const [formData, setFormData] = useState({
title: '',
contents: '',
active_cd: 'D',
top_yn: false,
});
useEffect(() => {
fetchNotices();
}, []);
const fetchNotices = async () => {
try {
const response = await axios.get('/notice/data/list.json');
setNotices(response.data.rows);
} catch (error) {
console.error('Failed to fetch notices:', error);
}
};
const handleRead = (notice) => {
setSelectedNotice(notice);
setFormData({
title: notice.title,
contents: notice.contents || '',
active_cd: notice.active_cd || 'D',
top_yn: notice.top_yn === 'Y',
});
};
const handleList = () => {
setSelectedNotice(null);
};
const handleChange = (e) => {
const { name, value, type, checked } = e.target;
setFormData((prevFormData) => ({
...prevFormData,
[name]: type === 'checkbox' ? checked : value,
}));
};
const handleUpdate = async () => {
if (!formData.title.trim()) {
alert('Title is required.');
return;
}
try {
const response = await axios.put(`data/list/${selectedNotice.ntc_idx}`, formData);
console.log('Notice updated successfully:', response.data);
fetchNotices();
setSelectedNotice(null);
} catch (error) {
console.error('Failed to update notice:', error);
}
};
const handleDelete = async () => {
try {
const response = await axios.delete(`data/list/${selectedNotice.ntc_idx}`);
console.log('Notice deleted successfully:', response.data);
fetchNotices();
setSelectedNotice(null);
} catch (error) {
console.error('Failed to delete notice:', error);
}
};
return (
React.createElement('div', { className: 'container mt-3' },
React.createElement('h2', null, 'Notice Admin Page'),
React.createElement('h5', null, 'Key Features: List inquiry/modification/deletion'),
React.createElement('p', null, 'Data is transmitted when modified or deleted from the test page, but it is not actually processed.'),
!selectedNotice ? (
React.createElement(NoticeList, { notices, handleRead })
) : (
React.createElement(NoticeForm, {
selectedNotice,
formData,
handleChange,
handleUpdate,
handleDelete,
handleList
})
)
)
);
}
NoticeAdminPage.js : React 와 BindModel 의 Mix
import React, { Component } from 'https://esm.sh/react';
import NoticeList from './NoticeList.js';
import NoticeForm from './NoticeForm.js';
import NoticeAdminService from '../service/notice-admin-svc.js'
export default class NoticeAdminPage extends Component {
constructor(props) {
super(props);
this.bm = new _L.BindModel(new NoticeAdminService(this));
this.bm.url = '/notice/data/list.json';
this.state = { selectedNotice: null };
}
componentDidMount() {
this.bm.cmd['list'].execute();
}
handleList = () => {
this.setState({ selectedNotice: null });
};
handleChange = (e) => {
let { name, value, type, checked } = e.target;
if (type === 'checkbox') value = checked ? 'Y' : 'N';
this.bm.cols[name].value = value; // column value setting
this.forceUpdate(); // Forced screen rendering
};
render() {
const { selectedNotice } = this.state;
return (
React.createElement('div', { className: 'container mt-3' },
React.createElement('h2', null, 'Notice Admin Page'),
React.createElement('h5', null, 'Key Features: List inquiry/modification/deletion'),
React.createElement('p', null, 'Data is transmitted when modified or deleted from the test page, but it is not actually processed.'),
React.createElement(NoticeList, { bindModel: this.bm }),
!selectedNotice || (
React.createElement(NoticeForm, {
handleChange: this.handleChange,
bindModel: this.bm
})
)
)
);
}
}
notice-admin-svc.js : React 와 BindModel 의 Mix
export default class NoticeAdminService {
constructor(reactThis) {
const _this = this;
this.items = {
title: { required: true }
},
this.command = {
create: {
},
read: {
outputOption: 3,
},
update: {
cbBind(bind, cmd, setup) {
console.warn('Caution: Send to the test server, but the data is not reflected.', setup.data);
},
cbEnd(status, cmd, res) {
if (res) {
alert('The post has been modified.');
reactThis.handleList();
}
}
},
delete: {
cbValid(valid, cmd) {
if (confirm('Are you sure you want to delete it?')) return true;
},
cbBind(bind, cmd, setup) {
console.warn('Caution: Send to the test server, but the data is not reflected.', setup.data);
},
cbEnd(status, cmd, res) {
if (res) {
alert('The post has been deleted.');
reactThis.handleList();
}
}
},
list: {
outputOption: 1,
cbEnd(status, cmd, res) {
reactThis.setState({ selectedNotice: null });
}
}
};
this.mapping = {
ntc_idx: { read: ['bind', 'output'], update: 'bind', delete: ['valid', 'bind'] },
title: { read: 'output', update: ['valid', 'bind'], },
contents: { read: 'output', update: 'bind' },
top_yn: { read: 'output', update: ['valid', 'bind'], },
active_cd: { read: 'output', update: ['valid', 'bind'], },
create_dt: { read: 'output' },
};
this.fn = {
handleRead: async (idx) => {
_this.bindModel.cmd['read'].outputOption.index = Number(idx);
await _this.bindModel.cmd['read'].execute();
reactThis.setState({ selectedNotice: true });
},
};
}
}
비교
혼합 코드에서 클래스 구성 요소와 BindModel을 사용하면 다음을 포함하여 React의 건강 관리와 비즈니스 로직을 더 명확하게 분리할 수 있는 이점을 얻을 수 있습니다.
- 비즈니스 로직의 재사용성 및 유지보수 개선: BindModel을 사용하면 비즈니스 로직과 구성 요소를 분리하고 관리할 수 있습니다. BindModel 내부에 데이터 바인딩 및 API 호출과 같은 로직을 정의함으로써 다른 구성 요소에서도 동일한 로직을 재사용할 수 있으며, 향후 로직 변경 시 유지보수가 용이합니다. 첫 번째 코드처럼 비즈니스 로직을 직접 구현하는 것보다 구조적으로 더 깔끔한 관리가 가능합니다.
- 데이터 바인딩 일관성: BindModel.this.bm.cols[name].value 와 동일한 방식으로 열 값을 관리하면 사용자 입력과 데이터 변경 사항을 효율적으로 동기화할 수 있어 데이터 바인딩 일관성을 보장할 수 있습니다.
- 명확한 건강 관리: 클래스 구성 요소는 건강 상태를 명시적으로 관리하며, BindModel과의 상호 작용을 통해 각 데이터의 상태 변화를 더 쉽게 추적할 수 있습니다. 이를 통해 구성 요소 간에 보다 체계적인 건강 관리가 가능합니다.
- 대규모 프로젝트의 유연성: 이 접근 방식은 크고 복잡한 프로젝트에 특히 유리합니다. BindModel은 여러 구성 요소에서 비즈니스 로직을 일관되게 처리할 수 있도록 지원하며 확장성과 유연성이 뛰어납니다.
결론적으로, 혼합 코드는 특히 대규모 프로젝트나 복잡한 데이터 처리의 경우 코드의 가독성, 유지보수 및 재사용성을 크게 개선하기 위해 React의 상태 관리와 비즈니스 로직을 명확하게 구분합니다.