2023. 6. 10. 17:21ㆍGithub 프로젝트/todolist반응형웹앱
지금까지 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
'Github 프로젝트 > todolist반응형웹앱' 카테고리의 다른 글
(10) TodoList 드래그앤드롭 적용하기 (0) | 2023.06.11 |
---|---|
(9) Todo List 클린 코드로 리팩토링 및 고도화 작업 (코드줄 줄이기, 분할, 필요없는 주석 제거 등) (0) | 2023.06.10 |
(7) Todo List Redux - Local Storage로 state 리팩토링 (0) | 2023.06.09 |
(6) Todo List 기본 기능 CRUD 추가 - 3 (삭제) (0) | 2023.06.08 |
(5) Todo List 기본 기능 CRUD 추가 - 2 (갱신) (0) | 2023.06.08 |