얼마전 웹에서 Json 데이터를 엑셀 파일로 저장하는 내용을 포스팅 했었다.
json 데이터가 있을 경우 엑셀 파일로 다운로드 되고 없을 경우 alert를 띄워줘야 하는데
우리는 시스템 alert가 아닌 custom alert modal을 사용했고 alert modal component을 만들면서 state update가 안됐던 것에 대해 이번에 글을 쓰고자한다.
처음 만들었던 코드
ExcelDownloadBtn.tsx
interface ExcelProps {
fileName: string;
dataSource?: any;
}
export const ExcelDownloadBtn = ({ fileName, dataSource }: ExcelProps) => {
const [showAlert, setShowAlert] = useState<boolean>(false);
const updateVisible = () => {
setShowAlert(!showAlert);
};
return (
<ExcelDownloadButtonStyled
onClick={() => (dataSource?.length === 0 ? setShowAlert(true) : downloadExcel(dataSource, fileName))}
>
<SaveIcon />
<ExcelFontStyled>엑셀로 저장</ExcelFontStyled>
<AlertModal
title="ㅤ"
message={['다운로드 받을 내역이 없습니다.', '검색 조건을 확인해주세요.']}
onClick={updateVisible}
showAlert={showAlert}
/>
</ExcelDownloadButtonStyled>
);
};
AlertModal.tsx
interface Props extends ModalProps {
message: string[];
onClick: () => void;
showAlert: boolean;
}
const AlertModal = (props: Props) => {
const { onOk, onClick, showAlert, onCancel, title } = props;
const [visible, setVisible] = useState<boolean>(showAlert);
useEffect(() => {
setVisible(showAlert);
}, [showAlert]);
return (
<Modal
title={title}
visible={visible}
{...props}
onCancel={onClick}
footer={
<ButtonWrapper>
<NegativeButton key="back" onClick={onCancel} style={negativeButtonStyle}>
취소
</NegativeButton>
<PositiveButton key="submit" onClick={onOk} style={positiveButtonStyle}>
확인
</PositiveButton>
</ButtonWrapper>,
}
>
<MessageStyled>
{props.message.map((e) => {
return <div style={messageStyled}>{e}</div>;
})}
</MessageStyled>
</Modal>
);
};
export default AlertModal;
AlertMdoal에 updateVisible 함수를 props로 전달하고 버튼을 클릭할 때 부모 컴포넌트에 있는 shoAlert의 상태값을 바꿔주는 형식으로 코드를 짰다.
당연히 실행되겠지 하고 버튼을 클릭했는데 updateVisible() 함수가 실행은 되나 showAlert 값이 업데이트 되지 않았다.
처음에는 rerender가 되지 않아 발생하는 문제라 생각하여 setTimeout 함수를 추가했으나 무한 루프가 돌아 버렸다.
너무 당연히 될 줄 알았던 코드라 계속 이상한 곳에서 원인을 찾다보니 어디가 잘 못 되었는지 찾기가 어려웠다.
그러다 부모 컴포넌트의 렌더링쪽을 확인해보니 다운로드 버튼안에 AlertModal component가 들어가 있었고 해당 컴포넌트를 버튼 밖으로 빼주었더니 state값이 정상적으로 변경되고 값이 변경됨에 따라 rerender도 정상적으로 일어났다.
수정 코드
return (
<>
<ExcelDownloadButtonStyled
onClick={() => (dataSource?.length === 0 ? setShowAlert(true) : downloadExcel(dataSource, fileName))}
>
<SaveIcon />
<ExcelFontStyled>엑셀로 저장</ExcelFontStyled>
</ExcelDownloadButtonStyled>
<AlertModal
title="ㅤ"
message={['다운로드 받을 내역이 없습니다.', '검색 조건을 확인해주세요.']}
onClick={updateVisible}
showAlert={showAlert}
/>
</>
);
'Javascript' 카테고리의 다른 글
Javascript에서의 동등 비교 (react 의존성 배열) (0) | 2023.12.30 |
---|---|
Iframe에서 부모 window와 통신하는 방법 (react, vue <=> iframe) (0) | 2023.06.07 |
[Javascript] node js로 정적 html 파일 서빙하기 (express) (0) | 2023.02.23 |
[Javascript] xlsx를 이용하여 json data를 엑셀 파일로 다운로드 하기 (초간단) (0) | 2023.02.22 |