2023. 4. 24. 17:05ㆍ개발일기
오늘의 학습 내용
- 공통 버튼, 모달, 커스텀 인풋, 커스텀 셀렉트박스 만들기 리팩토링
- useState 정리
새로운 배움
- useRef 사용 지양
- Array.prototype.map(), ****Array.prototype.forEach() in React Component
문제 상황과 시도, 해결
- 공통 버튼과 모달, 커스텀 인풋을 만들었던 프로젝트를 다시 다른 방법으로 만들어 보는 것을 시도해보았다. 처음에 만든 방법과 다른 방법으로 시도를 해보았는데 모달 팝업이 오픈될 경우 외부영역 클릭시 팝업 닫힘을 구현하고자 하였다. 이전에는 구글링하면 나오는 useRef를 사용한 방법을 통해 구현하였다. useRef는 돔요소를 직접 선택하기 때문에 사용을 지양한다는 말을 듣고 다른 방법으로 구현을 시도했다.
// 부모컴포넌트
function CustomModal() {
/** 호출하는 모달의 종류를 나타나내는 state
* confirm
* alert
* 초기값 : 어떤 모달도 호출하지 않는다.
*/
const [callModal, setCallModal] = useState()
// 버튼에 따라 가지고 오는 컴포넌트를 달리 한다.
const callModalFunc = (e) => {
if(e.target.innerText=='컨펌모달열기'){
setCallModal('confirm')
}else{
setCallModal('alert')
}
}
// 닫기 버튼이나 외부를 누를 경우 닫아주는 함수
const closeModalFunc = () =>{
setCallModal('')
}
return (
<commonSt.BtnBox>
<commonSt.Title>모달연습</commonSt.Title>
<commonSt.BtnBoxHAlign>
<Button id="confirm" size="s" type="primary" onClick={callModalFunc}>컨펌모달열기</Button>
<Button size="l" type="negative" onClick={callModalFunc}>얼럿모달열기</Button>
</commonSt.BtnBoxHAlign>
{(callModal==='confirm'&&callModal!=='')?<ConfirmModal lagacyFun={closeModalFunc}/>:(callModal==='alert'&&callModal!==''?<AlertModal lagacyFun={closeModalFunc}/>:<></>)}
</commonSt.BtnBox>
);
}
export default CustomModal;
- 각각 alert 모달과 confirm 모달을 컴포넌트로 만든 다음 CustomModal에서 불러왔다. 부모 컴포넌트인 CustomModal에서 각각의 자식 모달들을 스테이트 값에 따라 호출한다. - 이때 호출한 모달에 팝업을 종료하는 이벤트를 걸어주었다. - 외부 영역의 선택은 각각의 자식 모달에서 아웃레이어를 준 다음 해당 div의 영역을 css로 고정하고 z-index를 조절하여 모달레이아웃 바로 아래에 위치하게 한 다음 클릭 이벤트를 걸어주었다. 클릭이벤트는 부모 컴포넌트인 CustomModal에서 props로 내려주었다.
// 자식컴포넌트 중 하나인 AlertModal.jsx
import React from 'react';
import styled from 'styled-components';
function AlertModal(props) {
return (
<>
<ModalLayout>
<CloseBtn onClick={props.lagacyFun}>X</CloseBtn>
<ModalContent>얼럿모달 엑스 누르거나 외부 누르면 닫힘</ModalContent>
</ModalLayout>
<ModalOuter onClick={props.lagacyFun}></ModalOuter>
</>
);
}
const ModalLayout = styled.div`
width: 400px;
height: 200px;
border-radius: 3px;
background-color: white;
z-index: 2;
margin : 0 auto;
position: relative;
top: -400px;
`
const ModalOuter = styled.div`
display: flex;
top: 0;
width: 100%;
height: 100%;
position: absolute;
z-index: 1;
background-color: rgb(0,0,0, 0.7);
`
/* .. 버튼 CSS 생략 .. */
export default AlertModal;
- react Hook들에 대해 정리할 필요가 있을것같아 useState 부터 아는 내용을 차분히 정리하고 있었다. 책예서 읽은 내용들을 나만의 예제로 만들어 보고 있는 와중에 자바스크립트 Array를 반복문을 통해 컴포넌트 안에 나타내는 부분을 구현하고 있었다. - 인풋에 값을 입력하고 버튼을 클릭하면 해당 값을 배열에 넣으면서 화면 아래에 표시해주는 간단한 예제였는데 제대로 구현되지 않았다. 그리고 어떤 오류도 나지 않았다!
- 구글에 js Array.forEach react not working을 검색하자 바로 답을 알 수있었다.
- 똑같은 배열을 순회하는 메소드라고 하더라도 forEach는 요소에 접근해서 로직을 처리할 뿐 새로운 배열을 반환하지 않고 map은 로직을 처리하고 그 처리 결과가 반영된 새로운 배열을 반환하기 때문에 리턴으로 배열을 가진다. 따라서 forEach는 리턴이 없으므로 컴포넌트를 만들 수 없었던것! map으로 바꾸니 정상 동작 하였다.
느낀점
이전에 작성했던 동일한 기능의 코드라도 새로 작성해보니 새로운 방향이 나오고 더 코드가 깔끔해지는것 같았다. 계속 다른 방법은 없을까 고민해보는 습관이 중요한 것 같다.
간단한 에러였지만 역시 리액트를 잘 하기 위해선 자바스크립트 기본이 중요하다고 생각했다. 리턴으로 새로운 배열을 반환하지 않는다는 사실을 알고있었지만 막상 리액트 환경에서 까맣게 잊어버리다니!! 새로운 지식을 배우는 것도 중요하지만 알고있는 지식을 정리하는 경험이 중요한것 같다.
관련 작성글 바로가기
'개발일기' 카테고리의 다른 글
[TIL] 23.04.27. (2) | 2023.04.28 |
---|---|
[TIL] 23.04.26. (1) | 2023.04.26 |
[WIL] 23.04.17. - 23.04.22. (0) | 2023.04.23 |
[TIL] 23.04.22. (0) | 2023.04.23 |
[TIL] 23.04.21. (0) | 2023.04.21 |