두둥 너무 어렵습니다.
CRA를 먼저 완강을 하고 vite를 사용한 강의를 듣는게 맞았을까 싶기도 하구욤...
아직 useEffect나 라우트 등등 배울게 천리만리인데 지금까지 공부하고 작성한 코드도 겨우겨우 이해가 되는 중이다.
본캠프에서 리액트 배우고 vite 쓴다고 했으니까 급하게 완강하지 말고 공부할 수 있는 만큼, 제대로 코드를 아는게 좋을 것 같았다.
그래서 지금까지 작성한 jsx 파일을 정리한다 생각하고 복습하려한다..!
리액트 코드 정리
import { useState } from "react";
import PostsList from "./components/PostsList";
import MainHeader from "./components/MainHeader";
function App() {
const [modalIsVisible, setModalIsVisible] = useState(false); // false: 첫 화면에서 모달 안 보이게함
function showModalhandler() { //모달창 뜨게 하는 함수
setModalIsVisible(true);
}
function hideModalHandler() { //모달창 숨기는 함수
setModalIsVisible(false);
}
return (
<>
<MainHeader onCreatePost={showModalhandler} />
<main>
<PostsList isPosting={modalIsVisible} onStopPosting={hideModalHandler} />
</main>
</>
);
}
MainHeader
를 클릭하면 showModalhandler
에 의해 모달창이 열린다.PostsList
컴포넌트에서 isPosting
상태면 모달창이 보이고, onStopPosting
이면 모달창이 숨겨진다.import classes from './Post.module.css';
function Post(props) {
return (
<li className={classes.post}>
<p className={classes.author}>{props.author}</p>
<p className={classes.text}>{props.body}</p>
</li>
);
}
export default Post;
Post(props)
= Post{author, body}
로 변경 가능function PostsList({ isPosting, onStopPosting }) {
const [posts, setPosts] = useState([]);
function addPostHandler(postData) {//새로운 글 추가 함수
setPosts((existingPosts) => [postData, ...existingPosts]);
}
return (
<>
{isPosting ? (
<Modal onClose={onStopPosting}>
<NewPost
onCancel={onStopPosting} onAddPost={addPostHandler}
/>
</Modal>
) : false}
{posts.length > 0 && (
<ul className={classes.posts}>
{posts.map((post) => <Post key={post.body} author={post.author} body={post.body} />)}
</ul>
)}
{posts.length === 0 && <div style={{ textAlign: 'center', color: 'white' }}>
<h2>There are no posts yet.</h2>
<p>Start adding some!</p>
</div>}
</>
);
}
export default PostsList;
author
, body
값을 각각 객체로 담아둔 postData
를 가져와서 사용setPosts
는 이전에 작성된 포스트를 바탕으로 새로운 포스트가 추가되는 것setPosts
(새로 추가되는 내용)에 함수(화살표 함수같은 것)를 넘겨주어야한다.existingPosts
)의 스냅샷을 받고, 그 다음 새로운 상태 값을 반환해야한다.isPosting === true
이면 Modal
컴포넌트가 보여지고 NewPost
컴포넌트에 의해 글을 쓸 수 있다.NewPost
에는 버튼이 2개 있는데 하나는 취소(모달창 닫힘), 다른 하나는 추가(submit)되는 버튼이다.false
대신에 null
써도 됨 >> 모달창 사라짐Post key={post.body}
처럼 key
값을 적어주어야 원하는대로 값을 불러와서 보여질 수 있다.posts
의 개수가 1개 이상이면 post
객체값을 불러와서 보여준다posts
의 개수가 0, 즉 없으면 div
안 문장 보여진다.import classes from './NewPost.module.css';
import { useState } from 'react';
function NewPost({ onCancel, onAddPost }) {
const [enteredBody, setEnteredBody] = useState('');
const [enteredAuthor, setEnteredAuthor] = useState('');
function bodyChangeHandler(event) { // 내용 값 받아오는 함수
setEnteredBody(event.target.value);
}
function authorChangeHandler(event) { // 작성한 사람 값 받아오는 함수
setEnteredAuthor(event.target.value);
}
function submitHandler(event) { // 추가하기 버튼 값
event.preventDefault(); //기본 속성 방지
const postData = { // 작성자, 내용을 객체로 받아올 데이터
body: enteredBody,
author: enteredAuthor
};
onAddPost(postData); // 데이터를 받아서 포스트 추가
onCancel(); // 데이터 추가한 후 모달 창 닫음
}
return (
<form className={classes.form} onSubmit={submitHandler}>
<p>
<label htmlFor="body">Text</label>
<textarea id="body" required rows={3} onChange={bodyChangeHandler} />
</p>
<p>
<label htmlFor="name">Your name</label>
<input type="text" id="name" required onChange={authorChangeHandler} />
</p>
<p className={classes.actions}>
<button type="button" onClick={onCancel}>Cancel</button>
<button>Submit</button>
</p>
</form>
);
}
export default NewPost;
submitHandler
함수를 추가하면서 submit
버튼의 기본 속성을 막기 위해 event.preventDefault();
작성postData
안에 내용과 작성자 값을 객체로 담아주었다.postData
의 값을 받아와서 화면에 추가 onAddPost(postData)
하는 함수를 실행하고 그 다음 모달창을 닫기 위해 onCancel()
함수를 작성한다.postData
를 매개변수로 사용했기 때문에 위 3) PostsList.jsx 에서 사용할 수 있게 된다.import classes from './Modal.module.css';
function Modal({ children, onClose }) {
return (
<>
<div className={classes.backdrop} onClick={onClose} />
<dialog open className={classes.modal}>{children}
</dialog>
</>
)
}
export default Modal;
children
)는 다른 프로퍼티에도 사용 가능하다.Post
author
, body
로 내가 직접 속성과 이름을 만들어서 사용했지만 children은 다르다.children
이 참조하는 건 언제나 사용자정의 컴포넌트의 본문태그 안에 담겨 사용되는 콘텐츠이다. (예약된 속성임)이 children은 위에 코드들과 연결해서 설명이 필요하다.
잠시 PostsList
컴포넌트를 보면 Modal
컴포넌트를 만들어서 import하고 NewPost
를 Modal
태그로 래핑해준다.
백드롭 css로 살짝 회색빛은 보이는 효과는 성공했지만, "폼과 모달은 보이지 않는 문제가 발생한다"
그 이유는 어떤 콘텐츠(컴포넌트 or 다른 기본 내장 요소 등등) 를 다른 사용자 정의 컴포넌트(여기서는 Modal)로 래핑하면,
리액트는 컴포넌트의 어느 위치에 래핑된 콘텐츠를 표시해야 할지 알 수 없다.(Modal 컴포넌트 어디에 해야할지 모른다는 뜻)
따라서 리액트에게 어디에 표시해야할지 알려줘야 하는데 이때 children
을 사용하면 된다.
작성법은 props.children
으로 쓰거나 객체구조분해를 통해 {children}
으로 적을 수 있다.
이해한 선에서 복습하면서 정리한거라서 설명에 틀린 부분이 가득할 수 있슴다..
리액트를 조금 더 사용해보고 기초단계를 넘어서면 강의 코드를 다시 리뷰해야겠다.
출처