(8) Todolist 메인 부분 이외의 상세부분의 대해 CRUD 작성

2023. 6. 10. 17:21Github 프로젝트/todolist반응형웹앱

728x90
반응형
SMALL

지금까지 TodoList CRUD 및 UI 반응형 웹앱, Redux까지 반영을 시켰습니다.

 

Redux 반영에 대해서는 링크 참조 바랍니다. 

https://berkley.tistory.com/11

 

(7) Todo List Redux - Local Storage로 state 리팩토링

지금까지 CRUD 전체를 다루는 연습을 하였습니다. 이번 시간에는 Redux 설치 및 적용, Local Storage를 다루는 시간으로 활용 하겠습니다. 지금까지 따라오신 후 이 글을 확인하시기 바랍니다. (6) Todo Li

berkley.tistory.com

 

 

지금까지 React의 대해 기초를 다룰기 위해 Todolist 상위 분류만 CRUD를 적용을 시켰다면 다음은 소분류 CRUD 작성하는 시간을 가지겠습니다.

 

 

1. TodolList소분류 생성 (App.js)

이 작업은 입력 모드 설정과 입력 모드 제거를 위한 기능이므로 굳이 redux에 저장할 필요가 없다.

아래와 같이 추가한다.

  // todolist 소분류 추가 입력 모드 활성화 state
  const [isContentsAdd, setIsContentsAdd] = useState(false);
  const [createInputContents, setCreateInputContents] = useState();

 

다음으로는 입력용 state와 각각의 메소드 기능들을 셋팅합니다.

  /**
   * todolist 소분류 추가 작업 입력
   */
  const addContentsOnChange = (e, index) => {
    const { name, value } = e.target;
    setCreateInputContents({ [index]: { [name]: value } });
    console.log(createInputContents);
  };
  /**
   *  Todolist 소분류 추가하는 기능
   */
  const createContentsButton = (todo, index) => {
    let tmp = todo;
    tmp?.contents.push(createInputContents[index].contents);
    dispatch({
      type: "setTodoList",
      array: update(todoList, {
        $merge: {
          [index]: tmp,
        },
      }),
    });
  };

 

 

 

다음은 TodoList의 대분류의 추가 아이콘을 버튼으로 하여 + 버튼 누를 때마다 입력 모드, 입력모드 해제 기능을 수행하는 기능을 추가합니다.

 

이어서 입력모드 활성화 하는 UI에서 입력 기능과 추가 기능 버튼을 클릭하면 성공적으로 변환 시킬 수 있습니다.

  <div className="todo">
    {
      // 다음은 각각 데이터를 불려올 때 map을 주로 사용합니다.
      // todoList에 저장된 state 값을
      // 유사 forEach문처럼 todo를 이용하여 출력하고,
      // 상위 div에 key값을 설정하기 위해 index 값을 집어 넣어야 합니다.
      todoList?.map((todo, index) => (
        <div key={index} className="todoContainer">
          <div className="todoTitle">
            {isTitleUpdate ? (
              <div>
                <Input
                  name="title"
                  defaultValue={todo?.title}
                  onChange={(e) => updateTitlOnChange(e, index)}
                />
                <Button onClick={() => updateTitle(index)}>
                  todolist수정
                </Button>
                <Button
                  onClick={() => setIsTitleUpdate(!isTitleUpdate)}
                >
                  취소
                </Button>
              </div>
            ) : (
              <div>
                {todo?.title}
                <Button
                  onClick={() => setIsTitleUpdate(!isTitleUpdate)}
                >
                  수정
                </Button>{" "}
                {/* 이 부분 소분류 입력 모드 화면에 보이게 설정 */}
                <Button
                  onClick={() => setIsContentsAdd(!isContentsAdd)}
                >
                  <PlusCircle />
                </Button>
                {/* 이 부분 소분류 입력 모드 화면에 보이게 설정 끝 */}
                <Button onClick={() => removeTitle(index)}>
                  <Trash3 />
                </Button>
              </div>
            )}
          </div>

          {/* 이부분 + 버튼 누르면 입력모드 활성화 입력모드 해제 버튼 클릭 */}
          {isContentsAdd && (
            <>
              {"소분류 추가용 Input : "}
              <Input
                name="contents"
                // defaultValue={}
                onChange={(e) => addContentsOnChange(e, index)}
              />
              <Button onClick={() => createContentsButton(todo, index)}>
                추가
              </Button>
            </>
          )}
          {/* + 버튼 누르면 입력모드 활성화 입력모드 해제 버튼 클릭 끝 */}

          {todo?.contents?.map((tc, tcIndex) => (
            <div key={tcIndex} className="todoContents">
              - {tc} <Trash3 />
            </div>
          ))}
        </div>
      ))
    }
  </div>

 

 

 

2. TodolList소분류 갱신 (App.js)

다음은 소분류 갱신을 위한 기능을 추가합니다.

마찬가지로 대분류에서 작업한 것을 기대로 활용 하실 수 있습니다.

 

먼저 갱신 모드를 진행할 state 문을 생성합니다.

  // todolist 소분류 갱신모드 설정 여부
  const [isContentsUpdate, setIsContentsUpdate] = useState(false);


다음은 렌더링될 코드를 아래와 같이 수정합니다.

 

<수정 전>

  {todo?.contents?.map((tc, tcIndex) => (
    <div key={tcIndex} className="todoContents">
      - {tc} <Trash3 />
    </div>
  ))}

 

<수정 후>

  {todo?.contents?.map((tc, tcIndex) => (
    <div key={tcIndex} className="todoContents">
      {isContentsUpdate ? (
        <div>
          -
          <Input
            name="contents"
            defaultValue={tc}
            onChange={(e) =>
              updateContentsOnChange(e, index, tcIndex)
            }
          />
          <Button
            onClick={() => updateContents(index, tcIndex)}
          >
            todolist수정
          </Button>
          <Button
            onClick={() =>
              setIsContentsUpdate(!isContentsUpdate)
            }
          >
            취소
          </Button>
        </div>
      ) : (
        <div>
          - {tc}
          <Button
            onClick={() =>
              setIsContentsUpdate(!isContentsUpdate)
            }
          >
            수정
          </Button>{" "}
          <Button>
            <Trash3 />
          </Button>
        </div>
      )}
    </div>
  ))}

 

 

소분류 Update 기능을 구현합니다.

  /**
   * 소분류용 갱신 메서드 입력
   */
  const updateContentsOnChange = (e, index, tcIndex) => {
    const { name, value } = e.target;
    setUpdateInputContents({ [index]: { [tcIndex]: { [name]: value } } });
    console.log(updateInputContents);
  };

    /**
   * 소분류용 갱신 메서드 수행 = state 값 반영
   */
  const updateContents = (index, tcIndex) => {
    /**
     * 불변성 유지하면서 갱신 시킬 수 있습니다.
     */
    let contents = updateInputContents[index][tcIndex].contents;
    let to = todoList[index];
    to.contents[tcIndex] = contents;
    
    dispatch({
      type: "setTodoList",
      array: update(todoList, {
        [index]: { $set: to },
      }),
    });
  };

 

여기까지 하셨으면 갱신 가능합니다.

여기까지 진행하고 나니 불변성 함수의 활용 부분 면에서 좀 더 연습을 해야 할 것 같다는 느낌이 든다.

 

 

3. TodolList소분류 삭제 (App.js)

마지막으로 소분류 삭제를 진행 하도록 한다.

먼저 소분류에 렌더링 되어야 하는 Button 및 메소드 추가

  {todo?.contents?.map((tc, tcIndex) => (
    <div key={tcIndex} className="todoContents">
      {isContentsUpdate ? (
        <div>
          -
          <Input
            name="contents"
            defaultValue={tc}
            onChange={(e) =>
              updateContentsOnChange(e, index, tcIndex)
            }
          />
          <Button
            onClick={() => updateContents(index, tcIndex)}
          >
            todolist수정
          </Button>
          <Button
            onClick={() =>
              setIsContentsUpdate(!isContentsUpdate)
            }
          >
            취소
          </Button>
        </div>
      ) : (
        <div>
          - {tc}
          <Button
            onClick={() =>
              setIsContentsUpdate(!isContentsUpdate)
            }
          >
            수정
          </Button>{" "}
          <Button
          // 이부분 버튼 기능 추가
            onClick={() => removeContents(index, tcIndex)}
          >
            <Trash3 />
          </Button>
        </div>
      )}
    </div>
  ))}

 

 

다음으로는 아래와 같이 메서드 작성 (혹시 더 좋은 방법 있으면 그 방식대로 활용하시면 됩니다.)

  // 삭제 관련 메소드 (소분류)
  const removeContents = (index, tcIndex) => {
    let to = update(todoList[index].contents, {
      $splice: [[tcIndex, 1]],
    });

    console.log(to);

    dispatch({
      type: "setTodoList",
      array: update(todoList, {
          [index]: {
            contents: {$set: to},
          },
      }),
    });

    // console.log(tcIndex)
  };

 

 

 

 

여기 까지 완성 하셨으면, 소분류 crud 기능이 탑재가 되었습니다.

다음 시간에는 코드 리팩토링 및 분할에 대해서 만나도록 하겠습니다.

https://berkley.tistory.com/13

 

(9) Todo List 클린 코드로 리팩토링 및 고도화 작업 (코드줄 줄이기, 분할, 필요없는 주석 제거 등)

이전 시간 (8) Todolist 메인 부분 이외의 상세부분의 대해 CRUD 작성 : https://berkley.tistory.com/12 (8) Todolist 메인 부분 이외의 상세부분의 대해 CRUD 작성 지금까지 TodoList CRUD 및 UI 반응형 웹앱, Redux까지

berkley.tistory.com

 

728x90
반응형
LIST