Git Product home page Git Product logo

google_form_cloning's Introduction

구글 폼 클론 프로젝트

실행 방법

  1. npm 설치
npm install
  1. 프로젝트 빌드 후 실행
npm run build
npx serve -s build

구현 목록

  • 설문지 제목 추가, 편집

  • 설문지 설명 추가, 편집

  • 질문을 추가하면 질문이 추가됩니다.

    • 단답형
    • 장문형
    • 객관식 질문
    • 체크박스
    • 드롭다운
  • 질문 복사 기능

  • 질문 삭제 기능

  • 필수 옵션 설정 기능

  • 미리 보기 기능에서 해당 설문지를 미리볼 수 있어야 합니다!

    • 필수선택 기능
  • 사이드바

    • 반응형 추가
    스크린샷 2023-01-29 오전 8 09 54

시연 영상

https://youtu.be/EMUZo13ha0U

컴포넌트 종류

├── components/
│   ├── Preview/  
│   │   ├── ObjectiveOption/   
│   │   │   └── index.tsx
│   │   ├── OptionView/
│   │   │   └── index.tsx
│   │   └── SubjectiveOption/
│   │       └── index.tsx
│   ├── Question/ : 설문지에서 하나의 질문 로직을 다룹니다.
│   │   ├── Conatiner/  
│   │   │   ├── BottomContainer/
│   │   │   ├── MiddleContainer/
│   │   │   └── TopContainer/
│   │   ├── Options/  : 객관식과 주관식 컴포넌트로 나누어 구현하였습니다.
│   │   │   ├── ObjectiveOptions/
│   │   │   ├── SubjectiveOption/
│   │   │   └── index.tsx
│   │   └── index.tsx
│   ├── SideBar/ 
│   │   └── index.tsx
│   ├── Title/  : 설문지의 제목 관련 View&Logic 컴포넌트
│   │   └── index.tsx
│   └── common/   : 재사용 가능한 컴포넌트는 common폴더로 분리해주었습니다.
│       ├── BoxContainer/
│       │   └── index.tsx
│       ├── Dropdown/
│       │   └── index.tsx
│       └── FormContainer/
│           └── index.tsx

  • 질문 컴포넌트(Question/)는 총 세가지로 나뉩니다.
    • 제목이 포함된 TopContainer
    • 선택지작성이 포함된 MiddleContainer
    • 질문삭제 및 필수체크가 포함된 BottomContainer

트러블 슈팅

선택지(옵션) 추가삭제 어떻게 구현해야할까?

문제 상황

  • 선택지 추가를 어떻게 처리해야할 지 고민이었습니다.
  • 추가를 할 때마다 컴포넌트를 배열에 넣어 map으로 렌더링을 해야될까?
  • 그렇다면, 배열에 어떻게 컴포넌트를 넣을 지 고민이 되었습니다.

1차 구현

보통 여러 component를 구현할 때 map메소드를 많이 사용합니다.

이번 경우에도 map을 사용해보기 위해서는 각각의 component(하나의 option)에 대해 key값을 부여해줄 id가 필요합니다.

그래서 id를 저장하기 위한 list를 customHook으로 만들어주었습니다.

const useOptionList: UseOptionListProps = () => {
  const [list, setList] = useState<number[]>([]);

  const addOption = () => {
    setList((prev) => [...prev, list.length + 1]);
  };

  const removeOption = (id: number) => {
    // setList((prev) => )
  };

  return [list, addOption, removeOption];
};
export default useOptionList;

이 hook에서는 useState를 통해 생성한 list와 list에 요소를 추가하고 삭제하는 함수를 추가해준 후 반환해주었습니다.

요소를 추가해주는 로직은 어렵지 않았지만 문제는 요소를 삭제하는 로직이었습니다.

먼저 생각나는 로직은 다음과 같았습니다.

요소의 삭제버튼은 각각의 Option component 내부에 존재하므로 내부에서 스스로 component를 삭제하는 방식.

  • 이 경우 본인 컴포넌트를 삭제하는 함수를 props로 주입해주어야함.
  • 그래야 option component의 부모에서 변경을 인식하여 리렌더링하기 때문.

이정도의 고민을 통해 다음의 구현결과를 얻었습니다.

구현 결과

const useOptionList: UseOptionListProps = () => {
  const [list, setList] = useState<OptionType[]>([]);

  const addOption = () => {
    const newOption: OptionType = { id: list.length + 1 };
    setList((prev) => [...prev, newOption]);
  };

  const removeOption = (id: number) => {
    setList((prev) => prev.filter((option, idx) => option.id !== id));
  };

  return [list, addOption, removeOption];
};
export default useOptionList;

구현 결과, removeOption을 선택지 component에 넣어 선택지를 없애는 기능까지 추가할 수 있었습니다.

아쉬운 점

드롭다운에서 가운데에 있는 요소를 제거 시 index가 업데이트되지 않았습니다.

=> map 메소드에서 제공하는 index를 활용하여 구현해볼 수 있을 것 같습니다.

이 방식대로 개선해본 결과 정상적으로 고칠 수 있었습니다.

Redux 도입 이유

  1. 미리보기 기능

    • 미리보기기능은 단순하게 설문지 생성 화면에서 input 부분의 수정을 막아줌으로써 구현이 가능하긴 합니다.
    • 하지만, 단순히 input부분의 수정을 막기에는 과도한 조건문의 사용이 동반될 것 같아 고려하지 않았습니다.
    • 대신, redux를 통해 frontend의 상태값을 관리해주면 그 값을 이용하여 미리보기 페이지에서 활용해 볼 수 있다고 생각했습니다.
  2. 복사 기능

    • 질문을 복사할 때 질문에 있는 값(문제의 type, 선택지)을 그대로 옮겨서 새 질문box를 만들어야 합니다.
    • 이 때에는 input값을 그대로 옮겨와야 하므로 복사할 값을 전역상태를 통해 관리해주는 것이 적절하다고 생각했습니다.
    • 만약 전역상태를 활용해주지 않는다면 자식 component에서 부모 component로 값을 올려준 후 부모 component에서 질문box 생성 시 props로 넣는 방법도 있을 것입니다. 하지만, 자식 component에서 부모 component로 상태를 옮기는 것은 직관적이지 않고, 이미 redux로 질문값을 넣기로 결정 했다면 꺼내오기는 상대적으로 쉬우므로 redux를 사용하는 것이 적절하다고 생각했습니다.

google_form_cloning's People

Contributors

casebread avatar

Watchers

 avatar

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.