DiaryItem 컴포넌트
import { useState } from "react";
const DiaryItem =({author, content, create_date, emotion,id, onRemove}) => {
//수정하기 버튼을 눌렀을 때 일기 본무을 수정할 수 있는 폼이 나타나야 한다.
const [isEdit, setIsEdit] = useState(false);
// isEdit은 boolean값을 갖게 된다.
//(수정중인지 수정중이 아닌지를 boolean타입으로 값을 보관해 놓을 isEdit)
// isEdit state값이 'true'가 되면 jsx에서 '수정중'으로 간주한다.
// isEdit state값이 'false'가 되면 jsx에서 '수정중이 아닌 것'으로 간주한다.
const toggleIsEdit = () => setIsEdit(!isEdit);
//toggleIsEdit함수는 호출이 되는 순간 원래 isEdit이 갖고 있던 값을 반전시킨다.
//만약 isEdit값이 true였다면 toggleIsEdit함수는
//호출이 되는 순간 isEdit의 값은 false가 된다.
//수정 입력창에 적은 데이터들을 react에서 state로 핸들링
const [localContent, setLocalContent] =useState(content)
//수정버튼을 눌러 수정입력창이 나왔을떄 원래 일기 본문에 적혀져있던
//content값이 나오도록 초기값을 설정해둔다.
//삭제버튼 눌렀을때 실행되는 함수
const handleRemove = () => {
if(window.confirm(`${id}번쨰 일기를 정말 삭제하시겠습니까?`)){
onRemove(id)
}
}
return <div className="DiaryItem">
<div className="info">
<span>
작성자 : {author} | 감정점수 : {emotion}
</span>
<br />
<span className="date">{new Date(create_date).toLocaleDateString()}</span>
</div>
{/* 수정하기 버튼을 눌렀을시 일기 본문의 변화 */}
{/* isEdit이 true일떄 수정 입력창을 넣어주고 false일떄 원래 content값을 넣어준다. */}
<div className="content">
{isEdit ?
(<>
<textarea
value={localContent}
onChange={(e)=>{setLocalContent(e.target.value)}}
/>
</>) :
(<>
{content}
</>)
}
</div>
{isEdit ?
(<>
{/* 수정버튼을 눌렀을 때(isEdit의 값이 true일때) 버튼들이 바뀌게 만들어준다.
(수정취소버튼, 수정완료버튼) */}
<button onClick={toggleIsEdit}>수정취소</button>
{/* 수정취소버튼을 두르게 되면 isEdit의 값의 false로 바뀌게 된다.
그럼 isEdit의 값이 false일때의 버튼 형태가 나오게 된다. */}
<button >수정완료</button>
</>)
: (
<>
{/* 수정중이 아닐떄의 버튼들 */}
{/* 삭제버튼 */}
<button onClick={handleRemove}>삭제하기</button>
{/* 수정하기 버튼*/}
<button onClick={toggleIsEdit}>수정하기</button>
</>
)}
</div>
}
export default DiaryItem;
수정중일때
수정 중이 아닐때
DiaryItem컴포넌트
import { useState } from "react";
const DiaryItem =({author, content, create_date, emotion,id, onRemove}) => {
const [isEdit, setIsEdit] = useState(false);
const toggleIsEdit = () => setIsEdit(!isEdit);
const [localContent, setLocalContent] =useState(content)
//삭제버튼 눌렀을때 실행되는 함수
const handleRemove = () => {
if(window.confirm(`${id}번쨰 일기를 정말 삭제하시겠습니까?`)){
onRemove(id)
}
}
//수정하고 수정취소 버튼을 누르고 다시 수정하기 버튼을 눌렀을 때
//원래 content값이 나오도록 하는 함수(초기화시킨다.)
const handleQuitEdit = () => {
setIsEdit(false);
//수정취소버튼을 눌러 수정상태에서 나가는 것이기에 setIsEdit의 값이 false이다.
setLocalContent(content);
//수정 버튼을 눌러 켜진 수정입력창에 적혀져 있는 데이터는
//원래 일기 본문에 적혀져있던 데이터로 초기화 해준다.
}
return <div className="DiaryItem">
<div className="info">
<span>
작성자 : {author} | 감정점수 : {emotion}
</span>
<br />
<span className="date">{new Date(create_date).toLocaleDateString()}</span>
</div>
<div className="content">
{isEdit ?
(<>
<textarea
value={localContent}
onChange={(e)=>{setLocalContent(e.target.value)}}
/>
</>) :
(<>
{content}
</>)
}
</div>
{isEdit ?
(<>
<button onClick={handleQuitEdit}>수정취소</button>
{/* 수정 취소버튼이 눌릴때 handleQuitEdit함수가 실행된다. */}
<button >수정완료</button>
</>)
: (
<>
<button onClick={handleRemove}>삭제하기</button>
<button onClick={toggleIsEdit}>수정하기</button>
</>
)}
</div>
}
export default DiaryItem;
결과값
DiaryItem컴포넌트에 있는 수정완료 이벤트를 App컴포넌트로 보내기 위해서는 데이터를 가지고 있는 App컴포넌트의 수정하는 기능을 하는 함수를 하나 만들어서 DiaryItem컴포넌트까지 보내줘야 한다.
app컴포넌트
import { useState, useRef } from "react";
const DiaryItem =({author, content, create_date, emotion,id, onRemove, onEdit}) => {
const [isEdit, setIsEdit] = useState(false);
const toggleIsEdit = () => setIsEdit(!isEdit);
const [localContent, setLocalContent] =useState(content);
const localContentInput = useRef();
//삭제버튼 눌렀을때 실행되는 함수
const handleRemove = () => {
if(window.confirm(`${id}번쨰 일기를 정말 삭제하시겠습니까?`)){
onRemove(id)
}
}
const handleQuitEdit = () => {
setIsEdit(false);
setLocalContent(content);
}
//수정 완료 버튼을 눌렀을 떄 이벤트를 처리할 함수
const handleEdit = () =>{
// 수정한 데이터의 길이가 5글자 이상일때만 수정이 되도록 만들어준다.
if(localContent.length<5){
localContentInput.current.focus();
return;
}
if(window.confirm(`${id}번째 일기를 수정하시겠습니까?`)){
//예를 눌렀을 떄 onEdit함수 호출
// App컴포넌트에서 데이터가 수정이 되게 만들기 위해서 onEdit함수를 실행해야 한다.
// onEdit함수에 인자로 전달해야하는 값은 id(타겟아이디),localContent(새로 바뀌는 컨텐츠)이다.
onEdit(id, localContent);
//수정이 완료되었으면 수정폼을 닫아야 한다.
toggleIsEdit();
//수정중이였기에 값이 true였던 isEdit의 값을 false로 반환시켜서 수정폼을 닫는다.
}
}
return <div className="DiaryItem">
<div className="info">
<span>
작성자 : {author} | 감정점수 : {emotion}
</span>
<br />
<span className="date">{new Date(create_date).toLocaleDateString()}</span>
</div>
<div className="content">
{isEdit ?
(<>
<textarea
//textarea를 focus 할 거이기 떄문에 여기다가 레퍼런스 추가
ref ={localContentInput}
value={localContent}
onChange={(e)=>{setLocalContent(e.target.value)}}
/>
</>) :
(<>
{content}
</>)
}
</div>
{isEdit ?
(<>
<button onClick={handleQuitEdit}>수정취소</button>
{/* 수정 취소버튼이 눌릴때 handleQuitEdit함수가 실행된다. */}
<button onClick={handleEdit}>수정완료</button>
{/* 수정 완료 버튼을 눌렀을떄 handleEdit함수가 실행된다. */}
</>)
: (
<>
<button onClick={handleRemove}>삭제하기</button>
<button onClick={toggleIsEdit}>수정하기</button>
</>
)}
</div>
}
export default DiaryItem;
DiaryList 컴포넌트
//일기 리스트 컴포넌트
import DiaryItem from "./DiaryItem";
const DiaryList = ({onRemove, diaryList, onEdit}) => {
return <div className="DiaryList">
<h2>일기 리스트</h2>
<h4>{diaryList.length}개의 일기가 있습니다. </h4>
<div>
{diaryList.map((it)=>(
<DiaryItem onEdit={onEdit} onRemove= {onRemove} key={it.id} {...it}/>
))}
</div>
</div>
}
export default DiaryList;
DiaryItem 컴포넌트
import { useState, useRef } from "react";
const DiaryItem =({author, content, create_date, emotion,id, onRemove, onEdit}) => {
const [isEdit, setIsEdit] = useState(false);
const toggleIsEdit = () => setIsEdit(!isEdit);
const [localContent, setLocalContent] =useState(content);
const localContentInput = useRef();
//삭제버튼 눌렀을때 실행되는 함수
const handleRemove = () => {
if(window.confirm(`${id}번쨰 일기를 정말 삭제하시겠습니까?`)){
onRemove(id)
}
}
const handleQuitEdit = () => {
setIsEdit(false);
setLocalContent(content);
}
//수정 완료 버튼을 눌렀을 떄 이벤트를 처리할 함수
const handleEdit = () =>{
// 수정한 데이터의 길이가 5글자 이상일때만 수정이 되도록 만들어준다.
if(localContent.length<5){
localContentInput.current.focus();
return;
}
if(window.confirm(`${id}번째 일기를 수정하시겠습니까?`)){
//예를 눌렀을 떄 onEdit함수 호출
// App컴포넌트에서 데이터가 수정이 되게 만들기 위해서 onEdit함수를 실행해야 한다.
// onEdit함수에 인자로 전달해야하는 값은 id(타겟아이디),localContent(새로 바뀌는 컨텐츠)이다.
onEdit(id, localContent);
//수정이 완료되었으면 수정폼을 닫아야 한다.
toggleIsEdit();
//수정중이였기에 값이 true였던 isEdit의 값을 false로 반환시켜서 수정폼을 닫는다.
}
}
return <div className="DiaryItem">
<div className="info">
<span>
작성자 : {author} | 감정점수 : {emotion}
</span>
<br />
<span className="date">{new Date(create_date).toLocaleDateString()}</span>
</div>
<div className="content">
{isEdit ?
(<>
<textarea
//textarea를 focus 할 거이기 떄문에 여기다가 레퍼런스 추가
ref ={localContentInput}
value={localContent}
onChange={(e)=>{setLocalContent(e.target.value)}}
/>
</>) :
(<>
{content}
</>)
}
</div>
{isEdit ?
(<>
<button onClick={handleQuitEdit}>수정취소</button>
{/* 수정 취소버튼이 눌릴때 handleQuitEdit함수가 실행된다. */}
<button onClick={handleEdit}>수정완료</button>
{/* 수정 완료 버튼을 눌렀을떄 handleEdit함수가 실행된다. */}
</>)
: (
<>
<button onClick={handleRemove}>삭제하기</button>
<button onClick={toggleIsEdit}>수정하기</button>
</>
)}
</div>
}
export default DiaryItem;