Skip to content

Commit

Permalink
[8주차/현] 키워드 제출합니다
Browse files Browse the repository at this point in the history
[8주차/현] 키워드 제출합니다
  • Loading branch information
hyuke81 authored Nov 26, 2024
2 parents 0738c29 + 7d5fd84 commit 3cf12ab
Show file tree
Hide file tree
Showing 91 changed files with 17,111 additions and 0 deletions.
104 changes: 104 additions & 0 deletions keyword/chapter08/keyword.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
- useMutation 🍠
- useMutation이 무엇인가요?
- React-Query를 이용해 서버에 변경(insert, update, delete) 작업 요청 시 사용

```jsx
const deleteData = useMutation({
mutationFn: (id) => axios.delete(`api/delete/${id}`)
})

//axios를 이용해 서버에 API를 요청
```

- Mutate
- useMutation을 이용해 작성한 내용들이 실제로 실행될 수 있도록 돕는 trigger 역할
- useMutation을 정의해준 후, 이벤트 발생 시 사용

```jsx
const { mutate } = () => deleteData()

const deleteFn = () => {
deleteData.mutate(id)
}
```


- onMutate
- useMutation 훅에서 설정할 수 있는 옵션
- API 호출 전에 실행되는 함수
- 최적화된 업데이트를 위해 현재 데이터 캐시를 업데이트
- UI를 변경하는 등의 작업을 수행
- 업데이트가 성공적으로 이루어지지 않았을 때 사용할 수 있는 rollback 메커니즘도 제공
- onSuccess
- 요청이 성공되었을 때 실행됨

```jsx
onSuccess: (data: TData, variables: TVariables, context?: TContext) => Promise<unknown> | void
```

- onError
- 에러가 발생될 때 실행됨

```jsx
onError: (err: TError, variables: TVariables, context?: TContext) => Promise<unknown> | void
```

- onSettled
- finally 구문처럼 요청이 성공하든 에러가 발생되든 상관없이 마지막에 실행

```jsx
onSettled: (data: TData, error: TError, variables: TVariables, context?: TContext) => Promise<unknown> | void
```

- invalidateQueries
- useQuery에서 사용되는 queryKey의 유효성을 제거해주는 목적
- 왜 유효성을 제거?
- 서버로부터 다시 데이터를 조회해오기 위해서
- 왜 사용?
- useQuery에는 staleTime과 cacheTime이라는 개념이 존재하는데, 정해진 시간이 도달하지 않으면 새로운 데이터가 적재되었더라도 useQuery는 변동 없이 동일한 데이터를 화면에 보여줌
- 사용자 입장에서는 데이터 생성이 제대로 되었는지에 대한 파악이 힘들기 때문에 혼란을 겪을 수 있음
- 데이터를 저장할 때 invalidateQueries를 이용해 useQuery가 가지고 있던 queryKey의 유효성을 제거해주면 캐싱되어있는 데이터를 화면에 보여주지 않고 서버에 새롭게 데이터를 요청
- 데이터가 새롭게 추가되었을 때 다시 서버에서 데이터를 가져오게 되면서 추가한 데이터까지 화면에서 확인할 수 있음
- 낙관적 업데이트 (Optimistic Update) 🍠
- 낙관적 업데이트란?
- 서버로 요청을 보내기 전에 UI를 업데이트하는 것
- 데이터를 변경하려 할 때, **응답을 기다리기 전 미리 UI를 업데이트 시키는 것**
- 사용자 경험을 개선하고, 서버에서 응답을 받을 때까지 기다리지 않고 사용자에게 빠른 피드백을 제공
- 낙관적 업데이트를 `useMutation`을 활용하여 구현할 수 있는 방법?
- 쿼리 객체의 `onMutate`옵션을 활용!

```jsx
const queryClient = useQueryClient()
useMutation({
mutationFn: updateTodo,
// When mutate is called:
onMutate: async (newTodo) => {
// Cancel any outgoing refetches
// (so they don't overwrite our optimistic update)
await queryClient.cancelQueries({ queryKey: ['todos'] })
// Snapshot the previous value
const previousTodos = queryClient.getQueryData(['todos'])
// Optimistically update to the new value
queryClient.setQueryData(['todos'], (old) => [...old, newTodo])
// Return a context object with the snapshotted value
return { previousTodos }
},
// If the mutation fails,
// use the context returned from onMutate to roll back
onError: (err, newTodo, context) => {
queryClient.setQueryData(['todos'], context.previousTodos)
},
// Always refetch after error or success:
onSettled: () => {
queryClient.invalidateQueries({ queryKey: ['todos'] })
},
})
```

1. onMutate 콜백 함수에서 UI를 업데이트
2. setQueryData 함수를 사용하여 이전 데이터에서 업데이트
3. onError 콜백 함수에서는 에러가 발생했을 때 이전 데이터로 롤백
24 changes: 24 additions & 0 deletions mission/chapter08/mission1/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
8 changes: 8 additions & 0 deletions mission/chapter08/mission1/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# React + Vite

This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.

Currently, two official plugins are available:

- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
38 changes: 38 additions & 0 deletions mission/chapter08/mission1/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import js from '@eslint/js'
import globals from 'globals'
import react from 'eslint-plugin-react'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'

export default [
{ ignores: ['dist'] },
{
files: ['**/*.{js,jsx}'],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
parserOptions: {
ecmaVersion: 'latest',
ecmaFeatures: { jsx: true },
sourceType: 'module',
},
},
settings: { react: { version: '18.3' } },
plugins: {
react,
'react-hooks': reactHooks,
'react-refresh': reactRefresh,
},
rules: {
...js.configs.recommended.rules,
...react.configs.recommended.rules,
...react.configs['jsx-runtime'].rules,
...reactHooks.configs.recommended.rules,
'react/jsx-no-target-blank': 'off',
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
},
},
]
13 changes: 13 additions & 0 deletions mission/chapter08/mission1/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
Loading

0 comments on commit 3cf12ab

Please sign in to comment.