Giter Site home page Giter Site logo

tinycuteletterbox's Introduction

🐻‍❄️ 먼작귀 편지함

React를 이용한 먼작귀 캐릭터 팬레터 사이트 만들기 [ 먼작귀 편지함 ]


🔽 프로젝트 소개

프로젝트명 : 먼작귀 편지함

개발 기간 : 2024.01.29 ~ 2024.02.05

프로젝트 소개 : 먼작귀 캐릭터에게 편지를 보내고 편지함을 조회 및 수정, 삭제할 수 있는 팬레터 사이트 입니다.


🔽 개발 환경

  • Environment : vscode, github
  • Development : React, Javascript, JSX, HTML, CSS
  • Library : redux, router, styled-components, uuid
  • Design : Figma
  • Deployment: Vercel

🔽 시작 가이드

1. git clone

$ git clone https://github.com/seopport/TinyCuteLetterbox.git
$ cd TinyCuteLetterbox

2. yarn start

npm i
yarn start

🔽 와이어프레임

Home Page details Page
image-20240206100707847 image-20240206100736415
image-20240206100836019 image-20240206100846324

🔽 화면 구성 및 기능

1. 메인 페이지

Honeycam 2024-02-06 10-17-27
1.1. 편지 보내기
  • 드롭다운 박스로 편지를 보낼 캐릭터를 선택합니다.

    • 선택한 캐릭터에 따라 아래 편지함에서 해당 캐릭터의 편지함을 조회합니다.
  • 편지 내용과 작성자를 입력하고 편지를 보냅니다.

    • 편지 내용과 작성자 둘 중 하나라도 입력하지 않으면 알림창을 띄웁니다.
  • 편지를 보내면 편지함에 편지가 추가됩니다.

  • 편지 내용이 일정 글자 수를 넘어가면 점으로 요약되어 표시됩니다.


2. 상세 페이지

Honeycam 2024-02-06 10-19-50
2.1. 편지 상세 조회 및 수정
  • 메인 페이지에서 추가된 편지의 [상세보기]를 누르면 편지의 상세내용을 볼 수 있습니다.
  • 편지의 내용을 수정할 수 있습니다.
    • 수정 버튼을 누르면 완료, 취소 버튼이 나타납니다.
    • 취소 버튼을 눌렀을 때 수정 내역이 없으면 바로 수정이 취소되고, 수정 내역이 있으면 수정 취소를 확인하는 컨펌창을 띄워 사용자의 의사를 한번 더 확인하게 합니다.
    • 수정 내역이 없으면 완료 버튼을 누를 시 수정 사항이 없음을 알리고 수정되지 않습니다. 수정 내역이 있으면 해당 내용으로 수정이 완료됩니다.

Honeycam 2024-02-06 10-21-29
2.2. 편지 삭제
  • 삭제 버튼을 통해 편지를 삭제할 수 있습니다.
  • 편지를 삭제하면 알림창을 띄우고 메인 페이지로 이동합니다.

🚦 트러블 슈팅

1. 문제

아래의 그림은 기존 프로젝트의 컴포넌트와 전달받는 props들을 도식화한 것 입니다.

프로젝트 구조를 살펴보면 Home과 Detail 페이지에서는 단순히 props를 받아서 하위 컴포넌트로 전달하는 역할만을 수행하고 있었습니다. 이러한 prop-drilling으로 인해 컴포넌트 간의 데이터 전달이 복잡해지고 유지보수에 어려움이 있었습니다. 이에 따라 전역 상태 관리를 도입하여 프로젝트를 리팩토링하였습니다.

2. 시도 및 해결방안

2.1. context API 사용하기

아래의 그림은 context를 사용하여 리팩토링한 프로젝트 구조입니다.

앞서 언급한 문제를 해결하기 위해 context를 통해 state를 전역에서 관리하도록 수정하였습니다. 최상위 컴포넌트인 router.js 에서 편지를 저장하는 state를 정의하였고, 선택 캐릭터 정보는 Home컴포넌트에서만 쓰이기 때문에 Home 컴포넌트에서 정의하여 context로 관리하였습니다.


2.2. redux 사용하기

아래의 그림은 redux를 사용하여 리팩토링한 프로젝트 구조입니다.

이전에는 최상위 컴포넌트에서 편지 정보를 관리하고, Home 컴포넌트에서 선택된 캐릭터 정보를 관리하는 방식으로 context API를 사용했습니다. Redux를 사용하여 이러한 상태들을 중앙 store에서 관리하는 방식으로 리팩토링 해보았습니다. 모든 컴포넌트에서 동일한 상태에 접근할 수 있으므로 데이터 공유가 용이했고, 코드의 가독성과 유지보수성을 개선할 수 있었습니다.

tinycuteletterbox's People

Contributors

seopport avatar

Watchers

 avatar

tinycuteletterbox's Issues

피드백 - 박가현 튜터

안녕하세요, 지원님!
과제 구현하시느라 정말 고생 많으셨습니다.
전체적으로 아쉬운 부분이 거의 없을 정도로 과제 완성도가 매우 높아 열심히 공부하신 것이 빛을 발하고 있는 것 같습니다 :)
또한 readme에 기능 정리와 트러블 슈팅까지 깔끔하게 정리하신 부분이 인상깊었습니다.
추후 프로젝트를 복기할 때나 포트폴리오를 작성하실 때 유용할 것 같습니다.

#Props Drilling
<잘 구현된 부분>

  • 데이터 fetch, state와 set 함수를 적절한 곳에서 실행하고 선언하여 전체적인 컴포넌트 구조를 효율적으로 잘 짜셨습니다.
    const [savedLetters, setSavedLetters] = useState([]);
    useEffect(() => {
    const loadData = async () => {
    try {
    const res = await fetch("http://localhost:4000/data");
    const data = await res.json();
    setSavedLetters(data);
    } catch (error) {
    console.log(error);
    }
    };
    loadData();
    }, []);

#Context Api
<잘 구현된 부분>

  • context api의 사용 방법과 개념을 이해하고 올바른 방법으로 적용하였습니다.
    <BrowserRouter>
    <LetterContext.Provider
    value={{
    savedLetters,
    setSavedLetters,
    }}
    >
    <Routes>
    <Route path="/" element={<Home />} />
    <Route path="details/:id" element={<LetterDetailPage />} />
    </Routes>
    </LetterContext.Provider>
    </BrowserRouter>

#Redux(redux 브랜치 기준)
<잘 구현된 부분>

  • redux의 개념을 잘 이해하고 올바르게 사용하였습니다.
    const selectedCharacter = useSelector((state) => {
    return state.character.selectedCharacter
    })
    const dispatch = useDispatch();
    const handleCharacterBox = (character) => {
    dispatch(changeCharacter(character))
    }

<아쉬운 부분>

  • 리덕스 모듈에서 보통 액션 타입의 이름은 카멜 케이스보다는 대문자, 스네이크 케이스(SEND_LETTER)를 많이 사용합니다.
    https://ko.redux.js.org/usage/structuring-reducers/basic-reducer-structure
    export const SendLetter = "SendLetter";
    export const DeleteLetter = "DeleteLetter";
  • 비즈니스 로직 같은 경우는 reducer에서 구현해주시면 코드 재사용성이 더 높아집니다.
    const handleDeleteButtonClick = (id) => {
    if (window.confirm("편지를 삭제하시겠습니까?")) {
    const newSavedLetters = savedLetters.filter((item) => {
    return item.id !== id
    });
    dispatch(deleteLetter(newSavedLetters))
    alert('💌 편지를 삭제했습니다. 홈으로 이동합니다.');
    navigate('/')
    } return;
    };
    const [modifiedContent, setmodifiedContent] = useState('');
    const handleContentChange = (e) => {
    setmodifiedContent(e.target.value);
    }
    const [isModifying, setIsModifying] = useState(false)
    const handleModifyButtonClick = () => {
    setIsModifying(true);
    setmodifiedContent(contentArea.current.textContent)
    }
    const findLetter = (id) => {
    return savedLetters.find((item) => {
    return item.id === id
    })
    }
    const handleModifyCompleteButtonClick = (id) => {
    const originalLetter = findLetter(id)
    if (originalLetter.content === modifiedContent) {
    alert('수정 사항이 없습니다.');
    contentArea.current.focus();
    return;
    } else alert('💌 수정이 완료되었습니다.');
    setIsModifying(false);
    originalLetter.content = modifiedContent;
    }
  • context api를 사용하지 않음에도 context 폴더가 남아있습니다. 리덕스 프로젝트에서는 쓰지 않기 때문에 정리해주시는 것이 좋습니다.
  • 불필요한 주석은 구현을 마무리 할 때 삭제하면서 코드를 정리해주는 것이 좋습니다.
    //#region
    // useEffect(() => {
    // const loadData = async () => {
    // try {
    // const res = await fetch("http://localhost:4000/data");
    // const data = await res.json();
    // setSavedLetters(data);
    // } catch (error) {
    // console.log(error);
    // }
    // };
    // loadData();
    // }, []);
    //#endregion

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.