Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 크롬 익스텐션
- 자료구조
- 동적계획법
- nodejs
- 디스코드 봇
- discord.js
- react
- 백준
- C언어로 쉽게 풀어쓴 자료구조
- 백준 #7568번 #파이썬 #동적계획법
- background script
- webpack
- 공부시간측정어플
- Chrome Extension
- TypeScript
- 크롬 확장자
- supabase
- popup
- Message Passing
- content script
- 백준 7579
- 파이썬
- X
- 2156
- 포도주시식
- 캠스터디
- 갓생
- 프로그래머스 #정수삼각형 #동적계획법
Archives
- Today
- Total
히치키치
typescript-todo : createContext & useContext 작성 본문
💙 CreateContext
// /src/contexts/task-store.ts
import React, { createContext } from 'react';
import { Task } from '../types';
// 1. context 생성 : task가 원소인 리스트 (할 일들)
const TaskContext = createContext<
[Task[], React.Dispatch<React.SetStateAction<Task[]>>]
>([[], () => {}]);
export default TaskContext;
💙 useContext 훅 : useTaskStore
// /src/hooks/use-task-store.ts
import useLocalStorage from './use-local-storage';
import React, { useState, useContext, useEffect } from 'react';
import { Task } from '../types';
import { shuffle } from 'lodash';
import { nanoid } from 'nanoid';
import TaskContext from '../contexts/task-store';
const useTaskStore = () => {
// 1. useContext로 TaskContext 상태 사용
const [tasks, setTasks] = useContext(TaskContext);
// 2. FocusScreen에 띄울 할 일 id 설정
// useState로 초기값 정의
// filter 사용해 isComplete가 false로 구성된 task[] 만들고 그 중 첫번째 값의 id
const [focusedTaskId, setFocusedTaskId] = useState<string | undefined>(
tasks.filter((task) => !task.isComplete)[0]?.id
);
// 3. 2에서 정한 id에 해당하는 task를 tasks에서 find로 찾아서 값으로 설정
const focusedTask = tasks.find((task) => task.id === focusedTaskId);
// 4. task의 isComplete 여부를 update해 새로운 tasks 값 생성
const updateTaskCompletion = (taskId: string, isComplete: boolean) => {
// task의 id와 isComplete를 인자로 받음
setTasks((tasks) =>
tasks.map((task) => {
// tasks 배열을 map으로 돌면서
if (task.id === taskId) {
// 완료 여부가 변경된 task인 경우
return { ...task, isComplete };
//완료 여부를 update 해서 해당 task 요소를 반환
} else { // 완료 여부가 변경된 task가 아닌 경우
return task;
// 해당 task 요소 그대로 반환
}
})
);
};
useEffect(() => {
if (focusedTask?.isComplete) {
setFocusedTaskId(tasks.filter((task) => !task.isComplete)[0]?.id);
}
}, [tasks, focusedTask]);
// 5. filter를 통해 아직 완료되지 않은 할일 배열 생성
const shuffleFocusedTask = () => {
// filter를 통해 아직 완료되지 않은 할 일로만 구성된 배열 생성
// loadash 라이브러리의 shuffle 활용해 해당 배열의 순서를 바꿈
// 순서가 바뀐 배열의 첫번째 할 일을 focusScreen에 띄울 값으로 지정
setFocusedTaskId(shuffle(tasks.filter((task) => !task.isComplete))[0]?.id);
};
// 6. Pick 사용해 task 속성 중 label만 타입 검증
const addTask = (task: Pick<Task, 'label'>) => {
const id = nanoid();
setTasks((tasks) => [
...tasks, // 기존의 할 일들 갱신
{ id: id, label: task.label, isComplete: false }, // 새로운 할일 목록에 추가
]);
if (!focusedTaskId) {
//만약 최초로 task가 추가되어 focusScreen에 뜰 task가 지정되지 않은 상태인 경우
setFocusedTaskId(id); // 추가해...
}
};
const api = {
addTask,
focusedTask,
tasks,
setTasks,
updateTaskCompletion,
shuffleFocusedTask,
};
return api;
};
export default useTaskStore;
'typescript-todo' 카테고리의 다른 글
typescript-todo : localStorage에 tasks 저장을 위한 훅 작성 (0) | 2022.08.12 |
---|---|
typescript-todo : ListScreen & FocusScreen 작성 (0) | 2022.08.12 |
typescript-todo : 전역 상태관리 & Screen 구조, 함수 설계 (0) | 2022.08.12 |
typescript-todo : 요구사항/화면 구상 & 디렉토리 설정 & 기술스택 (0) | 2022.08.11 |
typescript-todo : types.ts 작성하여 할 일과 CRUD 타입 지정 (0) | 2022.08.11 |
Comments