#기초 컴포넌트 만들기 방법
import React, { useState, useEffect } from 'react';
import './App.css';
function App() {
}
const Modal = () => {
return (
<div className="detail">
<div className="content">
<h4>제목</h4>
<p>내용이다아아아아아</p>
</div>
</div>
);
};
export default App;
이렇게 App이라는 함수와 동등한 위치에 Modal이라는 함수를 만들고
html스트링을 return하게 만든다
그럼 이 함수는 Modal이라는 컴포넌트가 된다.
<Modal></Modal>
이걸 App()함수가 return하는곳 원하는곳에 쑤셔넣으면 됨
이렇게 Modal컴포넌트가 나타나게 되었다.
# 중요한점
컴포넌트는 무조껀 하나의 html태그를 return하게 만들어야 한다.
# css는?
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
p,
h4 {
margin: 0;
}
.App {
.black-nav {
display: flex;
justify-content: center;
background-color: black;
color: white;
padding: 5px;
height: 30px;
margin-bottom: 3px;
h4 {
text-align: left;
margin: 0;
}
}
.list {
background-color: navy;
color: blanchedalmond;
margin-bottom: 5px;
padding: 5px;
text-align: left;
p,
h4 {
margin: 0;
}
span {
color: green;
margin-left: 10px;
background-color: #eee;
border-radius: 3px;
padding: 2px;
}
}
.detail {
width: 100%;
display: flex;
justify-content: center;
.content {
background-color: #eee;
width: 97%;
height: 100px;
}
}
}
Modal이라는 함수를 따로 만들었지만 App컴포넌트에 해당 모달의 디자인 css코드를 담았다.
js관점으로 봤을때 Modal이 이후에 선언되었으니 호이스팅 오류가 생길줄 알았으나
알아서 잡아주는것 같음.
암튼 Modal 컴포넌트에 있는 html태그들의 css디자인을 App컴포넌트에서 설정해줘도
해당 css코드가 적용되서 오류없이 실행이 된다.
# 데이터바인딩
이렇게 하는지는 모르겠는데 그냥 App.js가 하나의 js문서니까 전역변수로 value라는 변수를 선언할당해줬다.
const value = '바보무찌';
이걸 App()컴포넌트와 Modal()컴포넌트에서 참조해봤더니
{value}
잘 불러온다.
리액트는 vue처럼 컴포넌트를 관리하는데 상당히 쉬울것 같다.
뭐 다른 방법이 있을수도 있겠지만..
대신 이 컴포넌트를 반복문으로 돌리고 각각 맞는 데이터 넣어주는건 아직 안배워서 배우면 알겠지.
# 동적 ui만들기(동적 컴포넌트)
const [modalState, setModalState] = useState({
detailModal: false,
});
이렇게 modal상태를 변수로 관리하는 객체를 만들었다.
강의에서는 객체로 안하는데 난 예전에 서비스 만들때 여러 모달상태를 여러 객체로 관리했어서
이렇게 객체로 만들어놨다.
true, false값에 따라 모달이 보이고 안보이고를 설정했다.
{modalState.detailModal ? <Modal></Modal> : null}
그리고 html리턴하는곳에 이렇게 3항연산자를 쓴다.
딥다이브 공부할때 문은 표현식이 아니고 삼항연산자는 표현식이다.
난 이 삼항연산자를 자주쓰고 많이 좋아했는데 이게 또 여기서 적용되나보다.
if문으로는 적용이 안된다.
vue는 v-if로 했는데 react는 좀 다르게 하는 부분임.
참고로 중괄호로 감싸줘야한다!
const changeDetailModalState = () => {
const copiedModalState = { ...modalState };
if (copiedModalState.detailModal) {
copiedModalState.detailModal = false;
} else {
copiedModalState.detailModal = true;
}
setModalState(copiedModalState);
};
이렇게 토글버튼에 넣을 함수를 만들어줬다.
스프레드문법 존나 자주 쓸듯..
<button onClick={changeDetailModalState}>모달토글</button>
이렇게 버튼에다가 onclick으로 해당 토글 함수를 갖다 넣으면 된다.
동작 잘됨
# 컴포넌트 props찍먹
일단 글 객체에다가 content키값을 넣었음.
const [titleLists, setTitleLists] = useState([
{
title: '남자 코트 추천',
date: '2024/07/11',
likeCount: 0,
content: '하잉1',
},
{
title: '여자 코트 추천',
date: '2024/07/12',
likeCount: 0,
content: '하잉2',
},
{
title: '남자 바지 추천',
date: '2024/07/13',
likeCount: 0,
content: '하잉3',
},
]);
해당 글 내용이다.
그리고 modalState에서 detailModalIndex를 넣어줬다.
const [modalState, setModalState] = useState({
detailModal: false,
detailModalIndex: 0,
});
현재 사용자가 보고있는 글 인덱스라는 뜻임.
const Modal = () => {
return (
<div className="detail">
<div className="content">
<h4>{titleLists[modalState.detailModalIndex].title}</h4>
<p>{titleLists[modalState.detailModalIndex].date}</p>
<p>{titleLists[modalState.detailModalIndex].content}</p>
</div>
</div>
);
};
그리고 이렇게 Modal html에다가 각 글내용에 해당되는 데이터를 넣어줬음
그런데 여기서 문제가 생김.
Modal함수와 App함수는 서로 별개의 함수이다. 즉 각함수에서 선언할당한 변수는 다른 함수가
참조를 못한다는 얘기. 변수생명주기, 실행컨텍스트 뭐 이것저것 관련되어있다.
그래서 최상단에 titleLists라는 데이터객체를 선언해주는걸로 바꿔줬더니 함수내에서만 useState를 사용할수 있다면서
또 막혔다.
그럼 이 데이터를 어떻게 참조할수 있게하느냐?
const Modal = ({ titleLists, modalState }) => {
return (
<div className="detail">
<div className="content">
<h4>{titleLists[modalState.detailModalIndex].title}</h4>
<p>{titleLists[modalState.detailModalIndex].date}</p>
<p>{titleLists[modalState.detailModalIndex].content}</p>
</div>
</div>
);
};
Modal컴포넌트 함수에서 각각 titleLists, modalState라는 변수를 매개변수로 선언한다
난 예전부터 딥다이브를 공부하면서 변수선언방법에는 매개변수도 포함된다고 생각했는데
역시나 이 맥락과 맞는다.
그다음 App에서 return하는 Modal html태그에서
{modalState.detailModal ? (
<Modal
titleLists={titleLists}
modalState={modalState}
setModalState={setModalState}
/>
) : null}
이렇게 titleLists와 ModalState, setModalState 데이터를 넘겨준다고 만들어줘야한다.
이건 react만의 문법인듯
이게 props임
그럼 원하는 기능이 잘 동작된다.
******중요!!!!!!
const Modal = ({ titleLists, modalState })
이렇게 모달 함수 만들때 꼭 매개변수를 객체로 넣어줘야한다.
복습할때
const Modal = (titleLists, modalState)
이렇게 매개변수로 각각 받아오려고 해서 안됐음.
리액트만의 방법인듯.
아 참고로 changeDetailModalState함수도 매개변수로 게시글 인덱스를 설정해줘야한다
const changeDetailModalState = (index) => {
const copiedModalState = { ...modalState };
if (!copiedModalState.detailModal) {
copiedModalState.detailModal = true;
copiedModalState.detailModalIndex = index;
} else if (copiedModalState.detailModalIndex == index) {
copiedModalState.detailModal = false;
} else {
copiedModalState.detailModalIndex = index;
}
setModalState(copiedModalState);
};
props를 안배운상태에서 gpt도움을 얻어서 원하는 기능이 동작된다
물론 react도 컴포넌트를 js파일별로 나눠서 관리하면 방법은 달라진다
export import사용하는듯?
근데 이 방법도 나름 괜찮은듯 하다.
반복문 배우면 더 응용될듯?
++ 컴포넌트 더할까?
사실 이 포스팅에서 배웠던게 그냥 그대로 다음강의에서 알려줌.
자잘한거 한개 더 쓰자면
- 부모 컴포넌트에서 자식컴포넌트에만 데이터 넘겨줄수 있음. 위로못옮김. vue에선 위로 옮기려면 emit이던데..
이게 다다..
# close 모달로 자식컴포넌트에서 부모컴포넌트 동작
이렇게 닫기버튼을 누르면 modal이 닫히는 기능을 만들거다.
const [modalState, setModalState] = useState({
detailModal: false,
detailModalIndex: 0,
});
닫기버튼을 누르면 저 detailModal이 true였는데 false로 바뀌게 하면됨
const closeModal = () => {
const copiedModalState = { ...modalState };
copiedModalState.detailModal = false;
setModalState(copiedModalState);
};
closeModal함수를 만들고
{modalState.detailModal ? (
<Modal
titleLists={titleLists}
modalState={modalState}
setModalState={setModalState}
closeModal={closeModal}
/>
) : null}
이걸 자식컴포넌트에 넘겨줌
const Modal = ({ titleLists, modalState, closeModal }) => {
return (
<div className="detail">
<div className="content">
<h4>{titleLists[modalState.detailModalIndex].title}</h4>
<p>{titleLists[modalState.detailModalIndex].date}</p>
<p>{titleLists[modalState.detailModalIndex].content}</p>
</div>
<button onClick={closeModal}>닫기</button>
</div>
);
};
위에 이미 사진으로 보여줬지만 닫기버튼을 만들어줌
-> 동작함
사실 emit이라는걸로 생각할필요없이 그냥 props로 넘겨준 closeModal함수를 호출하면
부모컴포넌트에서 closeModal함수가 호출되면서 setModalState함수가 호출이 된다.
딱히.. 굳이 생각할 필요없는 문제였음.. 예전 서비스에서 modal 복잡하게 class로 만들던게 생각나네..
'javaScript > react' 카테고리의 다른 글
onChange 이벤트(+이벤트 버블링 막기) (0) | 2024.07.23 |
---|---|
looooooooooop (0) | 2024.07.18 |
onClick이벤트 사용하기. (prettier, eslint설정) (0) | 2024.07.17 |
JSX & 데이터바인딩 (+JSX에서 html 태그 자동완성) (0) | 2024.07.17 |
react 프로젝트 설치 및 로컬서버 가동 (0) | 2024.05.27 |