지난번까지 완성 코드 :
- App.js
import { useRef, useState } from "react";
import "./Editor.css";
function Editor({ onCreateItem }) {
const [text, setText] = useState("");
const inputRef = useRef();
const onChangeInput = (event) => {
setText(event.target.value);
};
const onClickBtn = () => {
if (text === "") {
inputRef.current.focus();
return; //■순서1
}
onCreateItem(text);
setText("");
};
const onKeyDownInput = (event) => {
if (event.keyCode === 13) {
onClickBtn();
}
};
return (
<div className="Editor">
<input
ref={inputRef}
value={text}
onKeyDown={onKeyDownInput}
onChange={onChangeInput}
placeholder="새로운 Todo..."
/>
<button onClick={onClickBtn}>추가</button>
</div>
);
}
export default Editor;
- Editor.js
import { useRef, useState } from "react";
import "./Editor.css";
function Editor({ onCreateItem }) {
const [text, setText] = useState("");
const inputRef = useRef();
const onChangeInput = (event) => {
setText(event.target.value);
};
const onClickBtn = () => {
if (text === "") {
inputRef.current.focus();
return; //■순서1
}
onCreateItem(text);
setText("");
};
const onKeyDownInput = (event) => {
if (event.keyCode === 13) {
onClickBtn();
}
};
return (
<div className="Editor">
<input
ref={inputRef}
value={text}
onKeyDown={onKeyDownInput}
onChange={onChangeInput}
placeholder="새로운 Todo..."
/>
<button onClick={onClickBtn}>추가</button>
</div>
);
}
export default Editor;
1_ App 컴포넌트의 items를 List 컴포넌트에 전달하기
- 순서1_ App 컴포넌트 => List 컴포넌트 로 items 를 props로 전달
- App.js
function App() {
const [items, setItem] = useState(mockData);
const idRef = useRef(mockData.length); //id 식별을 위한, id에 대한 useRef() 객체 초기화
const onCreateItem = (context) => {
const newTodo = {
id: ++idRef.current, //새로운 item에 id 부여 후, id 증감
isDone: false,
content: context,
date: new Date().getTime(),
};
setItem([newTodo, ...items]);
};
return (
<div className="App">
<Header />
<Editor onCreateItem={onCreateItem} />
<List items={items} />//items를 List 컴포넌트에 전달
</div>
);
}
- 순서2_ List 컴포넌트에서 배열의 map() 메소드를 이용해, 모든 배열의 원소를 렌더링
■ key 설정
- List.js
import "./List.css";
import Todoitem from "./Todoitem";
function List({ items }) {
return (
<div className="List">
<p className="List-title">Todo List🌱</p>
<input placeholder="검색어를 입력하시오." />
<div className="List-contents">
{items.map((item)=>{
return <Todoitem key={item.id} item = {item} />;
//각 item을 Todoitem 컴포넌트의 key 설정, 각 data인 item 저날
})}
</div>
</div>
);
}
export default List;
■ <TodoItem>
컴포넌트에 각 배열의 객체 전달
- 순서3_
<TodoItem>
컴포넌트에 각 item의 프로퍼티값 적절하게 배치 출력
- Todoitem.js
import "./Todoitem.css";
function Todoitem({ item }) {//받은 data
const { isDone, content, date } = item; //변수로 프로퍼티들 추출 하는 법
return (
//적절하게 뽑은 프로퍼티값들을 출력
<div className="TodoItem">
<input type="checkbox" checked={isDone} />//checkbox일때, 값 대입 방법 기억해놓자
<p className="TodoItem-content">{content}</p>
<p className="TodoItem-date">{date}</p>
<button>삭제</button>
</div>
);
}
export default Todoitem;
- 출력 결과 :
&참고 :
{
id: 1,
isDone: true,
content: "빨래하기",
date: new Date().toISOString().split("T")[0],//date를 날짜 형식 출력 법임
},
2_ List에 검색 기능 구현해보기
-순서1_ search를 useState 변수 선언 , 검색 input에 입력된 값을 onChange 핸들러 구현, 등록
-순서2_ 업데이트 된 search값에 따라 items배열을 필터링 하는 메소드 구현 :
■ Search가 ""일 경우, => 그냥 모든 items 반환
■ 아니라면, filter(()=>{}) 메소드 이용 , include()메소드 이용하여, 해당되는 item들만 들어있는 items로 반환
■ ★filter((item)=>{}) 사용법 :
items.filter((item)=>{item.검색대상속성.includes(포함 검사 입력값)});
//s붙여야함
■ ▲ 한글이 있기에 => item의 content , 검색 대상 문자열 search 둘다 toLowerCase()로 모두 통일 해야한다.
itemsFilter()메소드 구현부
const itemsFilter = ()=>{
if(search==="") return items;
return items,filter((item)=>{item.content.include(search)});
}
-순서3_ itemsFilter()의 반환 값은 filter 후의 items이므로, 변수에 저장 후, map() 렌더링 부분에 반영
const filterItems = itemsFilter();
.
.
.
return (
<div className="List">
<p className="List-title">Todo List🌱</p>
<input value={search} placeholder="검색어를 입력하시오." />
<div className="List-contents">
{filterItems.map((item) => {//items를 filterItems로 코드 수정
return <Todoitem key={item.id} item={item} />;
})}
</div>
</div>
);
★ 응용_ 검색창에 입력 후, Enter 입력 시에만, items Filter 되도록 하는 코드 작성
List 컴포넌트
import { useState } from "react";
import "./List.css";
import Todoitem from "./Todoitem";
function List({ items }) {
const [search, setSearch] = useState(""); // 검색창 입력 상태
const [filterQuery, setFilterQuery] = useState(""); // 실제 필터링에 사용하는 상태
// 검색창 입력 시 호출
const onChangeSearch = (event) => {
setSearch(event.target.value);
};
// Enter 키 입력 시 호출
const onKeyDownSearch = (event) => {
if (event.key === "Enter") {
setFilterQuery(search); // filterQuery를 업데이트
}
};
// 필터링된 항목 계산
const getFilteredItems = () => {
if (filterQuery === "") return items; // 검색어가 없으면 전체 반환
return items.filter((item) =>
item.content.toLowerCase().includes(filterQuery.toLowerCase())
);
};
const filteredItems = getFilteredItems();
return (
<div className="List">
<p className="List-title">Todo List🌱</p>
<input
placeholder="검색어를 입력하시오."
onChange={onChangeSearch} // 검색창 입력
onKeyDown={onKeyDownSearch} // Enter 키 입력
value={search} // 입력 상태 연결
/>
<div className="List-contents">
{filteredItems.map((item) => (
<Todoitem key={item.id} item={item} />
))}
</div>
</div>
);
}
export default List;
- 출력 결과 :
'팀프로젝트_기록일지 > React_이정환_useState,useRef' 카테고리의 다른 글
(9).이정환_react.js강의_데이터의 수정 기능,데이터 삭제 기능 (0) | 2025.01.17 |
---|---|
(7).이정환_react.js강의_ List에 입력 후, 추가 , 삭제 구현 초기 셋팅 (0) | 2025.01.16 |
(6).이정환_react.js강의_ React's LifeCycle과 역할, LifeCycle_Control방=>useEffect (0) | 2025.01.15 |
(5).이정환_react.js강의_ 프로젝트_실습1_카운터프로그램 만들기 (0) | 2025.01.15 |
(4).이정환_react.js강의_ React의 Hook의 정의, 규칙, 커스텀 훅 만들기 (0) | 2025.01.14 |