React 사용
Toast ui Grid에서 Row를 더블 클릭했을 때 해당 행의 데이터를 상태관리툴에 저장하고 => 그 밑에 등록영역 ui에 해당 값들을 input의 value로 뿌려주는 과정에서 만난 어려움을 글로 남긴다.
const initialCheckboxState = {};
dummyData.forEach(item => {
initialCheckboxState[item.name] = false;
});
const [supplierCheckBoxState, setSupplierCheckBoxState] = useState([]); //선택한 값, 배열로 담아두는 곳
const [supplierCheckState, setSupplierCheckState] = useState(initialCheckboxState); //리스트 생성, true false값 저장
문제는 Grid에서 Row를 뽑아와서 등록영역에 뿌려줄 때이다.
//Zustand Store
export default function MarkupGrid({ gridData }) {
const gridRef = useRef(null);
const { insertMarkUpInputs, deleteGridRow, setInsertMarkUpInputs, setDeleteGridRow } = useMarkUp();
const { insertDefartureAndArrivalState, setInsertDefartureAndArrivalState } = useDefAndArrival();
//그리드의 행 더블클릭 시 해당 행의 값 저장
const onClickGridSelect = (e) => {
const { rowKey } = e;
const row = gridData.find((item) => item.rowKey === rowKey);
if (!row) {
return;
}
const selectGridRowData = {
iMarkUpID: row.markUpID || '',
iMarkUpTitle: row.markUpTitle || '',
iSupplierID: row.supplierID || '',
//생략
}
const selectGridRowData2 = { //다른 곳에서도 사용하기 때문에 따로 store를 만들어줬다.
iDepartureType: row.departureType || '',
iDepartureCode: row.departureCode || '',
iArrivalType: row.arrivalType || '',
iArrivalCode: row.arrivalCode || '',
}
setInsertMarkUpInputs(selectGridRowData);
setInsertDefartureAndArrivalState(selectGridRowData2);
}
//check한 행 저장
const checkGridRow = (e) => {
const { rowKey } = e;
const row = gridData.find((item) => item.rowKey === rowKey);
if (!row) {
return;
}
setDeleteGridRow([...deleteGridRow, row.markUpID]);
}
console.log("더블클릭시 저장1 ===>", insertMarkUpInputs)
console.log("더블클릭시 저장2 ===>", insertDefartureAndArrivalState)
console.log(deleteGridRow);
/*임시 dummyData*/
const gridOptions = {
columns: [
{ name: 'markUpID', header: '마크업IDX' },
{ name: 'markUpTitle', header: '제목' },
{ name: 'sellerID', header: '판매사' },
//생략
],
header: {
height: 50,
complexColumns: [
{
header: '마크업',
name: '11111111111111',
hideChildHeaders: false,
childNames: ['markUpType', 'ACI']
},
//생략
],
},
rowHeaders: ['checkbox'],
bodyHeight: 400,
}
useEffect(() => {
TuiGrid.applyTheme('clean');
}, []);
return (
<Grid
ref={gridRef} // 그리드 참조 설정
data={gridData}
columns={gridOptions.columns} {...gridOptions}
onDblclick={onClickGridSelect}
onCheck={checkGridRow}
onUncheck={(e) => console.log("onUncheck")}
/>
)
}
zustand를 설정하고, 그리드를 사용하는 페이지에서 해당 그리드 컴포넌트와 store를 import한다.
//page
const [insertGroupData, setInsertGroupData] = useState({
iMarkUpID: '', iMarkUpTitle: '', iSupplierID: '', iSellerID: '', //마크업ID //제목 //공급사ID /판매사ID
//생략
})
const { insertMarkUpInputs, deleteGridRow, removeAllInput } = useMarkUp();
const { insertDefartureAndArrivalState, removeDefAndArrivalInput } = useDefAndArrival();
useEffect(() => {
console.log("디버깅1", checkboxState);
console.log("디버깅2", insertMarkUpInputs);
console.log("디버깅3", insertDefartureAndArrivalState);
setInsertGroupData(prevData => ({
...prevData,
...insertMarkUpInputs,
...insertDefartureAndArrivalState,
iMarkUpID: insertMarkUpInputs.iMarkUpID || '',
iMarkUpTitle: insertMarkUpInputs.iMarkUpTitle || '',
iSupplierID: insertMarkUpInputs.iSupplierID || '',
iSellerID: insertMarkUpInputs.iSellerID || '',
//생략
iDepartureType: insertDefartureAndArrivalState.iDepartureType || '',
iDepartureCode: insertDefartureAndArrivalState.iDepartureCode || '',
iArrivalType: insertDefartureAndArrivalState.iArrivalType || '',
iArrivalCode: insertDefartureAndArrivalState.iArrivalCode || '',
//생략
}));
//판매사
const sellers = insertMarkUpInputs.iSellerID.split(',').map(seller => seller.trim());
setSellerCheckBoxState(sellers);
//여정타입
//좌석등급과 동일한 상황이어서 if문 추가
const tripTyps = insertMarkUpInputs.iTripType ? insertMarkUpInputs.iTripType.split(',').map(trip => trip.trim()) : [];
if (insertMarkUpInputs.iTripType.length !== 0) {
setCheckboxState({
oneWay: tripTyps.includes("RW"),
roundTrip: tripTyps.includes("OW"),
})
} else {
setCheckboxState({
oneWay: true,
roundTrip: true
});
}
//좌석등급
//처음 랜더링 될 때 useEffect로 랜더링 되면서 iCabin의 초기값이 ""가 되어
//처음 랜더링될 때 checkboxState가 true, ture 여야하는데 두번째 랜더링 때 false가 되어 버려 디폴트가 선택된 상태가 도무지 되지 않아. if문을 추가해 줌
const cabins = insertMarkUpInputs.iCabin.split(',').map(cabin => cabin.trim());
if (insertMarkUpInputs.iCabin.length !== 0) {
setCabinCheckState({
Y: cabins.includes('Y'),
P: cabins.includes('P'),
C: cabins.includes('C'),
F: cabins.includes('F')
})
} else {
setCabinCheckState({
Y: true,
P: true,
C: true,
F: true
})
}
}, [insertMarkUpInputs, insertDefartureAndArrivalState]);
insertGroupData : 등록영역 전체 input들의 상태를 관리하는 useState이다. post 요청 시 해당 useState의 값들을 보낸다.에러 발생
iDepartureCode 와 iArrivalCode 가 textarea에 값이 들어가졌다가 랜더링이 다시 되면서 값이 초기화되는 문제가 발생했다.useEffect(() => {
const updatedCheckboxState = {};
dummyData.forEach(item => {
updatedCheckboxState[item.name] = supplierCheckBoxState.includes(item.name);
});
setGroupData(prevData => ({
...prevData,
...insertInputs,
iSupplierID: insertInputs.iSupplierID || '',
}));
setSupplierCheckState(updatedCheckboxState);
}, [supplierCheckBoxState]);
setGroupData() 부분에서 데이터의 변화가 생기면서 useEffact가 한 번 더 실행되어 랜더링이 한 번 더 일어나는 문제였다. 해당 부분을 삭제하면서 정상적으로 작동하는 것을 확인했다.