1. props
일반 함수의 매개변수와 비슷하다고 생각하면 된다. props 는 부모 컴포넌트에서 자식 컴포넌트로 데이터를 넘길 때 사용한다. (역방향, 자식 -> 부모로는 불가능)
1.1. 함수형 컴포넌트에서 props 사용하기
부모 컴포넌트에서 "맑음" 을 넘겨주면 자식 컴포넌트에서 받아서 사용할 수 있다. 타입스크립트는 타입이 존재하기 때문에 자바스크립트와는 다르게 props 의 타입을 지정해줘야 한다.
// App.tsx -> 부모 컴포넌트
function App() {
return (
<div className='container'>
<MyWeather weather={"맑음"}></MyWeather>
</div>
);
}
export default App;
// MyWeather.tsx -> 자식 컴포넌트
interface MyProps {
weather: string;
children: React.ReactNode; // 컴포넌트의 자식요소
}
const MyWeather: React.FC<MyProps> = (props) => {
return (
<div>
오늘의 날씨는 {props.weather} 입니다.
</div>
)
}
export default MyWeather;
아래의 jsx 가 부모 컴포넌트의 일부라고 할 때, <MyWeather> 태그 사이에 있는 것을 부모 컴포넌트의 children 이라고 한다.
<MyWeather weather={"맑음"}>부모컴포넌트의 children</MyWeather>
그래서 자식컴포넌트에서는 props.children 으로 가져와서 사용할 수 있다.
<div>{props.children}</div>
그리고 props 의 값을 가져올 때도 구조분해할당을 사용하면 더 간단하게 사용할 수 있다.
interface MyProps {
weather: string;
children: React.ReactNode; // 컴포넌트의 자식요소
}
const MyWeather: React.FC<MyProps> = ({children, weather}) => {
return (
<div>
오늘의 날씨는 {weather} 입니다.
<div>{children}</div>
</div>
)
}
export default MyWeather;
1.2. 클래스형 컴포넌트에서 props 사용하기
this 를 통해 props 를 전달받을 수 있다. this 는 해당 컴포넌트 클래스 인스턴스 자체를 말한다.
import { Component } from 'react';
interface MyProps {
weather: string;
children: React.ReactNode; // 컴포넌트의 자식요소
}
class MyWeather extends Component<MyProps> {
render() {
const {children, weather} = this.props;
return (
<div>
오늘의 날씨는 {weather} 입니다.
<div>{children}</div>
</div>
)
}
}
export default MyWeather;
2. 모달창 띄우기
모달창은 리액트 부트스트랩에 만들어져 있는 것을 가져와서 사용하였다.
우선 props 의 타입을 지정해주었다.
- show -> 모달창을 보여줄 것인지 아닌지
- todo -> 투두 자체
- handleClose -> 모달창을 닫을 때 사용할 함수
// TodoModal.tsx
import { Modal } from 'react-bootstrap';
type Todo = {
id: number;
text: string;
isChecked: boolean;
};
type TodoModalProps = {
show: boolean;
todo: Todo | null;
handleClose: () => void;
}
const TodoModal : React.FC<TodoModalProps> = ({show, todo, handleClose}) => {
return (
<div>
<Modal show={show} onHide={handleClose} centered>
<Modal.Header closeButton>
<Modal.Title>Todo 상세정보</Modal.Title>
</Modal.Header>
<Modal.Body>{todo?.text}</Modal.Body>
</Modal>
</div>
);
}
export default TodoModal;
showDetail -> 모달창을 보여줄 것인지 여부를 나타내는 state
selectedTodo -> 현재 사용자가 어떤 투두 리스트를 클릭하였는지 TodoModal 컴포넌트로 보내주기 위한 state
handleTodoClick 함수는 span 태그가 클릭되면 클릭된 태그가 어떤 투두 리스트인지 TodoModal 에 알려주기 위한 state 인 selectedTodo 의 state 를 바꿔준다. (클릭된 투두 리스트로) 그리고 세부 사항 모달창을 띄워주기 위해 showDetail 을 true 로 바꾸어준다.
handleCloseDetail 은 모달창을 닫는 X 표시를 누르면 실행이 되는데, showDetail 을 false 로 바꾸어 모달창을 닫도록 한다.
// Todolist.tsx
import { useState } from "react";
import { Button } from 'react-bootstrap';
import TodoModal from "./\bTodoModal";
type Todo = {
id: number;
text: string;
isChecked: boolean;
};
const TodoList: React.FC = () => {
const title: string = "오늘 할 일";
const [todos, setTodos] = useState<Todo[]>([
{id: 0, text: '잠자기', isChecked: false },
{id: 1, text: '공부하기', isChecked: false },
{id: 2, text: '미팅하기', isChecked: false }
]);
// ...
const [showDetail, setShowDetail] = useState<boolean>(false);
const [selectedTodo, setSelectedTodo] = useState<Todo | null>(null);
const handleTodoClick = (todo: Todo) => {
setShowDetail(true)
setSelectedTodo(todo)
}
const handleCloseDetail = () => {
setShowDetail(false);
}
return (
<div>
<h1>{title}</h1>
<p></p>
<div className="container">
<div>
<input type="text"
placeholder="할 일 입력"
style={{marginRight: '10px',
writingMode: 'horizontal-tb'}}
onChange={(e) => setNewTodo(e.target.value)}
/>
<Button onClick={addTodo}>추가</Button>
</div>
<p></p>
<div className="board">
<ul>
{
todos.map((todo) =>
<li key={todo.id}>
<input type="checkbox"
onChange={() => {
handleCheckedChange(todo.id);
}}></input>
<span onClick={() => handleTodoClick(todo)}>
{
todo.isChecked ? <del>{todo.text}</del> : todo.text
}
</span>
<button className="del-button"
onClick={() => removeTodo(todo.id)}
>삭제</button>
</li>
)
}
</ul>
</div>
</div>
<TodoModal show={showDetail} todo={selectedTodo} handleClose={handleCloseDetail}></TodoModal>
</div>
)
}
export default TodoList;
'TIL with Programmers' 카테고리의 다른 글
[TIL] 11/5 프론트엔드 심화2 - 몰랐던 부분 정리 (0) | 2024.11.05 |
---|---|
[TIL] 11/4 프론트엔드 심화1 - 모르는거 정리 (0) | 2024.11.04 |
[TIL] 10/31 클래스/함수형 컴포넌트, useState (0) | 2024.10.31 |
[TIL] 10/30 리액트 기초-1 (0) | 2024.10.30 |
[TIL] 10/29 타입스크립트 기초-2 (1) | 2024.10.29 |