Skip to content

Commit 227280f

Browse files
committed
docs(typo): fix typos in extracting-state-logic-into-a-reducer.md
1 parent ad0fa64 commit 227280f

File tree

1 file changed

+21
-21
lines changed

1 file changed

+21
-21
lines changed

src/content/learn/extracting-state-logic-into-a-reducer.md

+21-21
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,22 @@ title: state 로직을 reducer로 작성하기
44

55
<Intro>
66

7-
한 컴포넌트에서 state 업데이트가 여러 이벤트 핸들러로 분산되는 경우가 있습니다. 이 경우 컴포넌트를 관리하기 어려워집니다. 따라서, 문제 해결을 위해 state를 업데이트하는 모든 로직을 *reducer*를 사용해 컴포넌트 외부로 단일 함수로 통합해 관리할 수 있습니다.
7+
한 컴포넌트에서 state 업데이트가 여러 이벤트 핸들러로 분산되는 경우가 있습니다. 이 경우 컴포넌트를 관리하기 어려워집니다. 따라서, 문제 해결을 위해 state를 업데이트하는 모든 로직을 *reducer*를 사용해 컴포넌트 외부의 단일 함수로 통합해 관리할 수 있습니다.
88

99
</Intro>
1010

1111
<YouWillLearn>
1212

1313
- reducer 함수란 무엇인가
14-
- `useState`에서 `useReducer`리펙토링 하는 방법
14+
- `useState`에서 `useReducer`리팩토링 하는 방법
1515
- reducer를 언제 사용할 수 있는지
1616
- reducer를 잘 작성하는 방법
1717

1818
</YouWillLearn>
1919

2020
## reducer를 사용하여 state 로직 통합하기 {/*consolidate-state-logic-with-a-reducer*/}
2121

22-
컴포넌트가 복잡해지면 컴포넌트의 state가 업데이트되는 다양한 경우를 한눈에 파악하기 어려워질 수 있습니다. 예를 들어, 아래의 `TaskApp` 컴포넌트는 state에 `tasks` 배열을 보유하고 있으며, 세 가지의 이벤트 핸들러를 사용하여 task를 추가, 제거 및 수정합니다:
22+
컴포넌트가 복잡해지면 컴포넌트의 state가 업데이트되는 다양한 경우를 한눈에 파악하기 어려워질 수 있습니다. 예를 들어, 아래의 `TaskApp` 컴포넌트는 state에 `tasks` 배열을 보유하고 있으며, 세 가지의 이벤트 핸들러를 사용하여 task를 추가, 제거 및 수정합니다.
2323

2424
<Sandpack>
2525

@@ -180,7 +180,7 @@ ul, li { margin: 0; padding: 0; }
180180

181181
</Sandpack>
182182

183-
각 이벤트 핸들러는 state를 업데이트하기 위해 `setTasks`를 호출합니다. 컴포넌트가 커질수록 그 안에서 state를 다루는 로직의 양도 늘어나게 됩니다. 복잡성를 줄이고 접근성을 높이기 위해서, 컴포넌트 내부에 있는 state 로직을 컴포넌트 외부의 **"reducer"라고 하는** 단일 함수로 옮길 수 있습니다.
183+
각 이벤트 핸들러는 state를 업데이트하기 위해 `setTasks`를 호출합니다. 컴포넌트가 커질수록 그 안에서 state를 다루는 로직의 양도 늘어나게 됩니다. 복잡성은 줄이고 접근성을 높이기 위해서, 컴포넌트 내부에 있는 state 로직을 컴포넌트 외부의 **"reducer"라고 하는** 단일 함수로 옮길 수 있습니다.
184184

185185
reducer는 state를 다루는 다른 방법입니다. 다음과 같은 세가지 단계에 걸쳐 `useState`에서 `useReducer`로 바꿀 수 있습니다.
186186

@@ -220,11 +220,11 @@ function handleDeleteTask(taskId) {
220220

221221
위 코드에서 state 설정 관련 로직을 전부 지워보세요. 다음과 같이 세가지 이벤트 핸들러가 남습니다.
222222

223-
- 사용자가 "Add" 를 눌렀을 때 호출되는 `handleAddTask(text)`
224-
- 사용자가 task를 토글하거나 "저장"을 누르면 호출되는 `handleChangeTask(task)`
225-
- 사용자가 "Delete" 를 누르면 호출되는 `handleDeleteTask(taskId)`
223+
- 사용자가 "Add"를 눌렀을 때 호출되는 `handleAddTask(text)`.
224+
- 사용자가 task를 토글하거나 "Save"를 누르면 호출되는 `handleChangeTask(task)`.
225+
- 사용자가 "Delete"를 누르면 호출되는 `handleDeleteTask(taskId)`.
226226

227-
reducer를 사용한 state 관리는 state 직접 설정하는 것과 약간 다릅니다. state를 설정하여 React에게 무엇을 할 지를 지시하는 대신, 이벤트 핸들러에서 action을 전달하여 사용자가 방금 한 일을 지정합니다. (state 업데이트 로직은 다른 곳에 있습니다!) 즉, 이벤트 핸들러를 통해 `tasks`를 설정하는 대신 task를 추가/변경/삭제하는 action을 전달하는 것입니다. 이러한 방식이 사용자의 의도를 더 명확하게 설명합니다.
227+
reducer를 사용한 state 관리는 state를 직접 설정하는 것과 약간 다릅니다. state를 설정하여 React에게 "무엇을 할 지"를 지시하는 대신, 이벤트 핸들러에서 "action"을 전달하여 "사용자가 방금 한 일"을 지정합니다. (state 업데이트 로직은 다른 곳에 있습니다!) 즉, 이벤트 핸들러를 통해 "`tasks`를 설정"하는 대신 "task를 추가/변경/삭제"하는 action을 전달하는 것입니다. 이러한 방식이 사용자의 의도를 더 명확하게 설명합니다.
228228

229229
```js
230230
function handleAddTask(text) {
@@ -282,7 +282,7 @@ dispatch({
282282

283283
### 2단계: reducer 함수 작성하기 {/*step-2-write-a-reducer-function*/}
284284

285-
reducer 함수는 state에 대한 로직을 넣는 곳 입니다. 이 함수는 현재의 state 값과 action 객체, 이렇게 두 개의 인자를 받고 다음 state 값을 반환합니다.
285+
reducer 함수는 state에 대한 로직을 넣는 곳입니다. 이 함수는 현재의 state 값과 action 객체, 이렇게 두 개의 인자를 받고 다음 state 값을 반환합니다.
286286

287287
```js
288288
function yourReducer(state, action) {
@@ -296,7 +296,7 @@ React는 reducer에서 반환한 값을 state에 설정합니다.
296296

297297
1. 첫 번째 인자에 현재 state (`tasks`) 선언하기.
298298
2. 두 번째 인자에 `action` 객체 선언하기.
299-
3. reducer에서 *다음* state 반환하기. (React가 state에 설정하게 될 값)
299+
3. reducer에서 *다음* state 반환하기 (React가 state에 설정하게 될 값).
300300

301301
다음은 state 설정과 관련 모든 로직을 reducer 함수로 마이그레이션한 코드입니다.
302302

@@ -359,7 +359,7 @@ function tasksReducer(tasks, action) {
359359
}
360360
```
361361

362-
각자 다른 `case` 속에서 선언된 변수들이 서로 충돌하지 않도록 `case` 블록을 중괄호인 `{``}`로 감싸는 걸 추천합니다. 또 `case`는 일반적인 경우라면 `return`으로 끝나야합니다. `return` 하는 것을 잊으면 코드가 다음 case로 "떨어져" 실수할 수 있습니다!
362+
각자 다른 `case` 속에서 선언된 변수들이 서로 충돌하지 않도록 `case` 블록을 중괄호인 `{``}`로 감싸는 걸 추천합니다. 또 `case`는 일반적인 경우라면 `return`으로 끝나야합니다. `return` 하는 것을 잊으면 코드가 다음 `case` "떨어져" 실수할 수 있습니다!
363363

364364
아직 switch 문에 익숙하지 않다면, if/else 문을 사용해도 괜찮습니다.
365365

@@ -469,9 +469,9 @@ const [tasks, setTasks] = useState(initialTasks);
469469
const [tasks, dispatch] = useReducer(tasksReducer, initialTasks);
470470
```
471471

472-
`useReducer` 훅은 초기 state 값을 입력받아 유상태(stateful) 값을 반환한다는 점과 state를 설정하는 함수(useReducer의 경우는 dispatch 함수를 의미)의 원리를 보면 `useState`와 비슷합니다. 하지만 조금 다른 점이 있습니다.
472+
`useReducer` hook은 초기 state 값을 입력받아 유상태(stateful) 값을 반환한다는 점과 state를 설정하는 함수(`useReducer` 경우는 dispatch 함수를 의미)의 원리를 보면 `useState`와 비슷합니다. 하지만 조금 다른 점이 있습니다.
473473

474-
`useReducer` 훅은 두 개의 인자를 넘겨받습니다.
474+
`useReducer` hook은 두 개의 인자를 넘겨받습니다.
475475

476476
1. reducer 함수
477477
2. 초기 state 값
@@ -670,7 +670,7 @@ ul, li { margin: 0; padding: 0; }
670670

671671
</Sandpack>
672672

673-
아래 처럼 reducer를 다른 파일로 분리하는 것도 가능합니다.
673+
아래처럼 reducer를 다른 파일로 분리하는 것도 가능합니다.
674674

675675
<Sandpack>
676676

@@ -884,7 +884,7 @@ reducer가 좋은 점만 있는 것은 아닙니다! 아래에서 `useState`와
884884

885885
reducer를 작성할 때, 다음과 같은 두 가지 팁을 명심하세요.
886886

887-
- **Reducers는 반드시 순수해야 합니다.** [state updater functions](/learn/queueing-a-series-of-state-updates)와 비슷하게, reducer는 렌더링 중에 실행됩니다! (action은 다음 렌더링까지 대기합니다.) 이것은 reducer는 [반드시 순수](/learn/keeping-components-pure)해야한다는 걸 의미합니다.즉, 입력 값이 같다면 결과 값도 항상 같아야 합니다. 요청을 보내거나 timeout을 스케쥴링하거나 사이드 이펙트(컴포넌트 외부에 영향을 미치는 작업) 수행해서는 안 됩니다. reducer는 [objects](/learn/updating-objects-in-state)[arrays](/learn/updating-arrays-in-state)변이 없이 업데이트해야 합니다.
887+
- **Reducer는 반드시 순수해야 합니다.** [state 업데이트 함수](/learn/queueing-a-series-of-state-updates)와 비슷하게, reducer는 렌더링 중에 실행됩니다! (action은 다음 렌더링까지 대기합니다.) 이것은 reducer는 [반드시 순수](/learn/keeping-components-pure)해야한다는 걸 의미합니다. 즉, 입력 값이 같다면 결과 값도 항상 같아야 합니다. 요청을 보내거나 timeout을 스케쥴링하거나 사이드 이펙트(컴포넌트 외부에 영향을 미치는 작업) 수행해서는 안 됩니다. reducer는 [객체](/learn/updating-objects-in-state)[배열](/learn/updating-arrays-in-state)변경하지 않고 업데이트해야 합니다.
888888

889889
- **각 action은 데이터 안에서 여러 변경들이 있더라도 하나의 사용자 상호작용을 설명해야 합니다.** 예를 들어, 사용자가 reducer가 관리하는 5개의 필드가 있는 양식에서 ‘재설정’을 누른 경우, 5개의 개별 `set_field` action보다는 하나의 `reset_form` action을 전송하는 것이 더 합리적입니다. 모든 action을 reducer에 기록하면 어떤 상호작용이나 응답이 어떤 순서로 일어났는지 재구성할 수 있을 만큼 로그가 명확해야 합니다. 이는 디버깅에 도움이 됩니다!
890890

@@ -1096,30 +1096,30 @@ ul, li { margin: 0; padding: 0; }
10961096

10971097
</Sandpack>
10981098

1099-
reducer는 순수해야 하기 때문에, 이 안에서는 state를 변형할 수 없습니다. 그러나, Immer에서 제공하는 특별한 `draft`객체를 사용하면 안전하게 state를 변형할 수 있습니다. 내부적으로, Immer는 변경 사항이 반영된 `초안(draft)`으로 state의 복사본을 생성합니다. 이것이 `useImmerReducer` 가 관리하는 reducer가 첫 번째 인수인 state를 변형할 수 있고 새로운 state 값을 반환할 필요가 없는 이유입니다.
1099+
reducer는 순수해야 하기 때문에, 이 안에서는 state를 변경할 수 없습니다. 그러나, Immer에서 제공하는 특별한 `draft` 객체를 사용하면 안전하게 state를 변경할 수 있습니다. 내부적으로, Immer는 변경 사항이 반영된 `draft` state의 복사본을 생성합니다. 이것이 `useImmerReducer`가 관리하는 reducer가 첫 번째 인수인 state를 변형할 수 있고 새로운 state 값을 반환할 필요가 없는 이유입니다.
11001100

11011101
## 요약 {/*요약*/}
11021102

1103-
- `useState`에서 `useReducer`로 변환하려면:
1103+
- `useState`에서 `useReducer`로 변환하려면
11041104
1. 이벤트 핸들러에서 action을 전달합니다.
11051105
2. 주어진 state와 action에 대해 다음 state를 반환하는 reducer 함수를 작성합니다.
11061106
3. `useState``useReducer`로 바꿉니다.
11071107
- reducer를 사용하면 코드를 조금 더 작성해야 하지만 디버깅과 테스트에 도움이 됩니다.
11081108
- reducer는 반드시 순수해야 합니다.
11091109
- 각 action은 단일 사용자 상호작용을 설명해야 합니다.
1110-
- 객체와 배열을 변이하는 스타일로 reducer를 작성하려면 Immer 라이브러리를 사용하세요.
1110+
- 객체와 배열을 변경하는 스타일로 reducer를 작성하려면 Immer 라이브러리를 사용하세요.
11111111

11121112
<Challenges>
11131113

11141114
#### 이벤트 핸들러에서 action 전달하기 {/*dispatch-actions-from-event-handlers*/}
11151115

1116-
현재 `ContactList.js``Chat.js`의 이벤트 핸들러 안에는 `// TODO` 주석이 있습니다. 이 때문에 input에 값을 입력해도 동작하지 않고 탭 버튼을 클릭해도 선택된 수신인이 변경할 수 없습니다.
1116+
현재 `ContactList.js``Chat.js`의 이벤트 핸들러 안에는 `// TODO` 주석이 있습니다. 이 때문에 input에 값을 입력해도 동작하지 않고 탭 버튼을 클릭해도 선택된 수신인을 변경할 수 없습니다.
11171117

1118-
`// TODO` 주석이 있는 부분을 지우고 상황에 맞는 action을 `전달(dispatch)`하는 코드를 작성해보세요. action에 대한 힌트를 얻고 싶다면 `messengerReducer.js`에 구현된 reducer를 확인해보세요. 이 reducer는 이미 작성되어있기 때문에 변경할 필요가 없습니다. 여러분은 `ContactList.js``Chat.js`에 action을 담아 전달하는 코드를 작성하기만 하면 됩니다.
1118+
`// TODO` 주석이 있는 부분을 지우고 상황에 맞는 action을 `dispatch`하는 코드를 작성해보세요. action에 대한 힌트를 얻고 싶다면 `messengerReducer.js`에 구현된 reducer를 확인해보세요. 이 reducer는 이미 작성되어있기 때문에 변경할 필요가 없습니다. 여러분은 `ContactList.js``Chat.js`에 action을 담아 전달하는 코드를 작성하기만 하면 됩니다.
11191119

11201120
<Hint>
11211121

1122-
`dispatch` 함수는 컴포넌트의 prop으로 전달되기 때문에 이미 두 컴포넌트 모두에서 사용할 수 있습니다. 따라서 알맞은 action 객체를 담아 `dispatch` 를 호출하면 됩니다.
1122+
`dispatch` 함수는 컴포넌트의 prop으로 전달되기 때문에 이미 두 컴포넌트 모두에서 사용할 수 있습니다. 따라서 알맞은 action 객체를 담아 `dispatch`를 호출하면 됩니다.
11231123

11241124
action 객체를 어떻게 작성해야하는지 확인하고 싶다면, reducer를 보고 어떤 `action` 필드가 들어갈지 유추할 수 있습니다. reducer에 정의된 `changed_selection`의 경우를 예를 들어 보겠습니다.
11251125

0 commit comments

Comments
 (0)