[간단 일기장] React에서 배열 사용하기 (4. 데이터 수정하기)

미아·2023년 1월 5일
0

REACT

목록 보기
16/41

button 코드 가독정 좋게 바꾸기


=> 원래 코드는 button onClick안에 함수가 들어있었는데, 이는 보기 불편하므로
=> 변수만들어서 함수를 저장해둔후, 호출하는 방식으로!

수정하기


=> 수정하기 버튼을 누르면 표시한 부분이 폼으로 바뀌면서 수정가능하게 바꿀거다!

😎언제나 데이터를 수정하려면? useState!
-> 수정하는 데이터는 item있는곳에서만 데이터 바꾸면 되는거라서, DiaryItem에서 만지면 되는건가?


-> useState로 t/ f 상태 파악해서 -> 수정하게 해두고

  • textarea안에서 수정할 폼은 또 다른 useState로 수정하자!


=> 수정하기 버튼 누르고 그 값을 기억하고 그걸로 바꾸게

수정완료하고 => 값을 바꾸려면

  • 언제나 데이터는 부모에서 => 자식 컴포넌트로 전달해야하므로
    app.js에서 건드려야함!

DiaryItem.js

import { useRef, useState } from "react";

const DiaryItem = ({
  author,
  content,
  created_date,
  emotion,
  id,
  onRemove,
  onEdit,
}) => {
  const [isEdit, setIsEdit] = useState(false);
  // 수정중일때는 boolean타입으로 상태를 파악한후, 수정가능하게 만들거다!
  const toggleIsEdit = () => setIsEdit(!isEdit);
  //toggle => 상태를 반전시킨다는 뜻, 수정폼 열고 닫는용도
  const localContentInput = useRef();

  //toggle이 호출되면 isEdit가 가지고 있는 상태의 반대 결과값이 나오게!
  const [localContent, setLocalContent] = useState(content);
  //content로 받아줘야, 원래 들어있던 content가 나옴

  /* 수정취소 : 누르면, 원래 있던 내용이 나와야함(만약 사용자가 더 값을 입력해도, contetn만)*/
  const handleQuitEdit = () => {
    setIsEdit(false); //수정상태에서 나가야하므로
    setLocalContent(content);
  };
  /* 수정완료 : 누르면, 부모에게서 받아온 데이터 가지고 그 값을 content에 넣게*/
  const handleEdit = () => {
    //5글자 안넘으면 focus 들어가게!(useRef)
    if (localContent.length < 5) {
      localContentInput.current.focus();
      return;
    }
    if (window.confirm(`${id}번째 일기를 수정하시겠습니까?`)) {
      onEdit(id, localContent);
      toggleIsEdit(); //닫아주기
    }
  };
  const handleRemove = () => {
    if (window.confirm(`${id}번째 일기를 정말 삭제하시겠습니까?`)) {
      onRemove(id); //prop으로 DiaryItem에게 전달했으니까, 사용가능~
    }
  };
  return (
    <div className="DiaryItem">
      <div className="info">
        <span>
          작성자: {author} | 감정점수 : {emotion}
        </span>
        <br />
        <span className="date">{new Date(created_date).toLocaleString()}</span>
        {/* ms로 저장했던 date를 .toLocaleString()이용해서 한국시간으로 바꿔준다~~ */}
      </div>
      {/* 수정하기 버튼을 누르면, 새로운 폼이 뜨고, 아닐경우 content가 보여야한다. */}
      <div className="content">
        {isEdit ? (
          <>
            {/* textarea안에 수정하면 수정한 값이 담기게 해줄것임(localContent) */}
            <textarea
              value={localContent}
              onChange={(e) => setLocalContent(e.target.value)}
              ref={localContentInput}
            />
          </>
        ) : (
          <>{content}</>
        )}
      </div>
      {isEdit ? (
        <>
          <button onClick={handleQuitEdit}>수정취소</button>
          <button onClick={handleEdit}>수정완료</button>
        </>
      ) : (
        <>
          <button onClick={handleRemove}>삭제하기</button>
          <button onClick={toggleIsEdit}>수정하기</button>
        </>
      )}
    </div>
  );
};
export default DiaryItem;

App.js

import { useRef, useState } from "react";
import "./App.css";
import DiaryEditor from "./DiaryEditor";
import DiaryList from "./DiaryList";
function App() {
  // app -> editor 적용할 데이터
  const [data, setData] = useState([]); // 빈 배열, 앞으로 채워넣을것임
  const dataId = useRef(0);

  // 전달해줄 함수 onCreate
  const onCreate = (author, content, emotion) => {
    const created_date = new Date().getTime();
    const newItem = {
      author, // 비구조화 할당맞다, 키랑 이름 맞추면 그대로 들어감
      content,
      emotion,
      created_date,
      id: dataId.current,
    };
    dataId.current += 1; //current에 1 더해줘야함
    setData([newItem, ...data]); //setData를써야
  };

  // 삭제해줄 함수 onRemove , 어떤 아이디를 갖고있는 애를 지우면 됨!
  const onRemove = (targetId) => {
    console.log(`${targetId}가 삭제되었습니다.`);
    const newDiaryList = data.filter((it) => it.id !== targetId); //다른것만 뉴배열에 넣어라~
    console.log(newDiaryList); // 기억하기!! setData함수 안쓰면 삭제는 진행 안됨!
    setData(newDiaryList);
  }; // 얘를 지우려면, DiaryItem에 가서 지워야함(컴포넌트 전달은 부모인 DiaryList에게!)

  // 수정해줄 함수 onEdit
  const onEdit = (targetId, newContent) => {
    //targetId, newContent 받아가지고와서 => 그 아이디 일치하는 애만 바꿔주면됨
    //데이터 바꾸려면 ? setData()사용~
    //새로운 데이터를 넘겨줘야함!
    setData(
      data.map(
        (it) => (it.id === targetId ? { ...it, content: newContent } : it)
        // ...it 들어온 데이터 뿌려주고, content만 새로운 content로!
      )
    );
  };
  return (
    <div className="App">
      <DiaryEditor onCreate={onCreate} />
      <DiaryList onRemove={onRemove} diaryList={data} onEdit={onEdit} />
      {/* prop으로 전달함!(부모=> 자식컴포넌트로 데이터 전달!) */}
    </div>
  );
}

export default App;

-> 수정할 함수인 onEdit확인해서 id일치하는지 확인하고 newContent 넘겨받아서 저장하면됨 (map메소드로)

profile
새로운 것은 언제나 재밌어 🎶

0개의 댓글