Skip to content

Commit d7abe3a

Browse files
committed
Merge remote-tracking branch 'origin/main' into sync-2a2e02f1
2 parents 26934d2 + 27f7a48 commit d7abe3a

27 files changed

+2359
-248
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,6 @@ public/fonts/**/Optimistic_*.woff2
3939

4040
# rss
4141
public/rss.xml
42+
43+
# textlint
44+
wiki/textlint/translate-glossary.md

.textlintrc

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"filters": {
3+
"comments": true
4+
}
5+
}

.textlintrc.js

-6
This file was deleted.

package.json

+8-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@
2020
"start": "next start",
2121
"postinstall": "patch-package && (is-ci || husky install .husky)",
2222
"check-all": "npm-run-all prettier lint:fix tsc rss",
23-
"rss": "node scripts/generateRss.js"
23+
"rss": "node scripts/generateRss.js",
24+
"textlint-test": "yarn mocha ./textlint/tests/utils && yarn mocha ./textlint/tests/rules",
25+
"textlint-docs": "node ./textlint/generators/genTranslateGlossaryDocs.js",
26+
"textlint-lint": "yarn textlint ./src/content --rulesdir ./textlint/rules -f pretty-error"
2427
},
2528
"dependencies": {
2629
"@codesandbox/sandpack-react": "2.13.5",
@@ -77,6 +80,7 @@
7780
"lint-staged": ">=10",
7881
"mdast-util-to-string": "^1.1.0",
7982
"metro-cache": "0.72.2",
83+
"mocha": "^10.6.0",
8084
"npm-run-all": "^4.1.5",
8185
"patch-package": "^6.2.2",
8286
"postcss": "^8.4.5",
@@ -94,6 +98,9 @@
9498
"retext-smartypants": "^4.0.0",
9599
"rss": "^1.2.2",
96100
"tailwindcss": "^3.4.1",
101+
"textlint": "^14.0.4",
102+
"textlint-filter-rule-comments": "^1.2.2",
103+
"textlint-tester": "^14.0.4",
97104
"typescript": "^4.0.2",
98105
"unist-util-visit": "^2.0.3",
99106
"webpack-bundle-analyzer": "^4.5.0"

src/content/learn/choosing-the-state-structure.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ State를 잘 구조화하면 수정과 디버깅이 즐거운 컴포넌트와
2626
4. **State의 중복 피하기.** 여러 상태 변수 간 또는 중첩된 객체 내에서 동일한 데이터가 중복될 경우 동기화를 유지하기가 어렵습니다. 가능하다면 중복을 줄이세요.
2727
5. **깊게 중첩된 state 피하기.** 깊게 계층화된 state는 업데이트하기 쉽지 않습니다. 가능하면 state를 평탄한 방식으로 구성하는 것이 좋습니다.
2828

29-
이러한 원칙 뒤에 있는 목표는 *오류 없이 상태를 쉽게 업데이트하는 것* 입니다. State에서 불필요하고 중복된 데이터를 제거하면 모든 데이터 조각이 동기화 상태를 유지하는 데 도움이 됩니다. 이는 데이터베이스 엔지니어가 [데이터베이스 구조를 "정규화"](https://docs.microsoft.com/en-us/office/troubleshoot/access/database-normalization-description)하여 버그 발생 가능성을 줄이는 것과 유사합니다. 알베르트 아인슈타인의 말을 빌리자면, **"당신의 state를 가능한 한 단순하게 만들어야 한다, 더 단순하게 가 아니라."**
29+
이러한 원칙 뒤에 있는 목표는 *오류 없이 상태를 쉽게 업데이트하는 것* 입니다. State에서 불필요하고 중복된 데이터를 제거하면 모든 데이터 조각이 동기화 상태를 유지하는 데 도움이 됩니다. 이는 데이터베이스 엔지니어가 [데이터베이스 구조를 "정규화"](https://learn.microsoft.com/ko-kr/office/troubleshoot/access/database-normalization-description)하여 버그 발생 가능성을 줄이는 것과 유사합니다. 알베르트 아인슈타인의 말을 빌리자면, **"당신의 state를 가능한 한 단순하게 만들어야 한다, 더 단순하게 가 아니라."**
3030

3131
이제 이 원칙들이 실제로 어떻게 적용되는지 살펴보겠습니다.
3232

@@ -98,7 +98,7 @@ body { margin: 0; padding: 0; height: 250px; }
9898

9999
<Pitfall>
100100

101-
State 변수가 객체인 경우에는 다른 필드를 명시적으로 복사하지 않고 [하나의 필드만 업데이트할 수 없다](/learn/updating-objects-in-state)는 것을 기억하세요. 예를 들어, 위의 예제에서는 `y` 속성이 전혀 없기 때문입니다 `setPosition({ x: 100 })`를 할 수 없습니다! 대신, `x`만 설정하려면 `setPosition({ ...position, x: 100 })`을 하거나 두 개의 state 변수로 나누고 `setX(100)`을 해야 합니다.
101+
State 변수가 객체인 경우에는 다른 필드를 명시적으로 복사하지 않고 [하나의 필드만 업데이트할 수 없다](/learn/updating-objects-in-state)는 것을 기억하세요. 예를 들어, 위의 예제에서는 `y` 속성이 전혀 없기 때문입니다. `setPosition({ x: 100 })`를 할 수 없습니다! 대신, `x`만 설정하려면 `setPosition({ ...position, x: 100 })`을 하거나 두 개의 state 변수로 나누고 `setX(100)`을 해야 합니다.
102102

103103
</Pitfall>
104104

src/content/learn/reacting-to-input-with-state.md

+6-6
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ UI 인터랙션을 디자인할 때 유저가 액션을 하면 어떻게 UI를 *
2929

3030
<Illustration src="/images/docs/illustrations/i_imperative-ui-programming.png" alt="In a car driven by an anxious-looking person representing JavaScript, a passenger orders the driver to execute a sequence of complicated turn by turn navigations." />
3131

32-
옆에 탄 운전기사는 당신이 어디를 가고싶어 하는지 모릅니다. 그저 명령에 따를 뿐이죠. (잘못된 지시를 하면 잘못된 곳에 도착하고 말겁니다.) 우리가 이것을 *명령형*이라 부르는 이유입니다. 왜냐하면 컴퓨터에게 스피너에서부터 버튼까지 각각의 요소에 UI를 *어떻게* 업데이트 해야할지 "명령"을 내려야하기 때문이죠.
32+
옆에 탄 운전기사는 당신이 어디를 가고싶어 하는지 모릅니다. 그저 명령에 따를 뿐이죠. (잘못된 지시를 하면 잘못된 곳에 도착하고 말겁니다.) 우리가 이것을 *명령형*이라 부르는 이유입니다. 왜냐하면 컴퓨터에게 스피너부터 버튼까지 각각의 요소에 UI를 *어떻게* 업데이트 해야할지 "명령"을 내려야하기 때문이죠.
3333

3434
아래의 명령형 UI 프로그래밍 예제는 리액트 *없이* 만들어진 폼입니다. 브라우저에 내장된 [DOM](https://developer.mozilla.org/ko/docs/Web/API/Document_Object_Model)을 사용했습니다.
3535

@@ -131,7 +131,7 @@ body { font-family: sans-serif; margin: 20px; padding: 0; }
131131

132132
</Sandpack>
133133

134-
위의 예시에서는 문제가 없겠지만 위와 같이 UI를 조작하면 더 복잡한 시스템에서는 난이도가 기하급수적으로 올라갑니다. 여러 다른 폼으로 가득 찬 페이지를 업데이트해야 한다고 생각해보세요. 새로운 UI 요소나 새로운 인터랙션을 추가하려면 버그의 발생을 막기 위해 기존의 모든 코드를 주의 깊게 살펴봐야만 할 겁니다 (예를 들면 어떤 것을 보여주거나 숨기거나 하는 것을 잊을지도 모릅니다).
134+
위의 예시에서는 문제가 없겠지만 위와 같이 UI를 조작하면 더 복잡한 시스템에서는 난이도가 기하급수적으로 올라갑니다. 여러 다른 폼으로 가득 찬 페이지를 업데이트해야 한다고 생각해보세요. 새로운 UI 요소나 새로운 인터랙션을 추가하려면 버그의 발생을 막기 위해 기존의 모든 코드를 주의 깊게 살펴봐야만 할 겁니다. (예를 들면 어떤 것을 보여주거나 숨기거나 하는 것을 잊을지도 모릅니다).
135135

136136
리액트는 이러한 문제점을 해결하기 위해 만들어졌습니다.
137137

@@ -151,7 +151,7 @@ body { font-family: sans-serif; margin: 20px; padding: 0; }
151151

152152
## 첫 번째: 컴포넌트의 다양한 시각적 state 확인하기 {/*step-1-identify-your-components-different-visual-states*/}
153153

154-
여러가지 "state"를 가지고 있는 ["상태 기계"](https://ko.wikipedia.org/wiki/유한_상태_기계)라는 것을 컴퓨터 과학에서 들어본 적이 있을 것입니다. 그리고 디자이너와 일한다면 다양한 "시각적 state"에 관한 모형을 본 적이 있을 것입니다. 리액트는 디자인과 컴퓨터 과학의 사이에 있기 때문에 두 아이디어 모두에게서 영감을 받았습니다.
154+
여러가지 "state"를 가지고 있는 ["상태 기계"](https://ko.wikipedia.org/wiki/유한_상태_기계)라는 것을 컴퓨터 과학에서 들어본 적이 있을 것입니다. 그리고 디자이너와 일한다면 다양한 "시각적 state"에 관한 모형을 본 적이 있을 것입니다. 리액트는 디자인과 컴퓨터 과학의 사이에 있기 때문에 두 아이디어 모두에서 영감을 받았습니다.
155155

156156
먼저 사용자가 볼 수 있는 UI의 모든 "state"를 시각화해야 합니다.
157157

@@ -346,9 +346,9 @@ Form states
346346
347347
### 세 번째: 메모리의 state를 `useState`로 표현하기 {/*step-3-represent-the-state-in-memory-with-usestate*/}
348348
349-
다음으로 [`useState`](/apis/usestate)를 사용하여 컴포넌트의 시각적 state를 표현해야 합니다. 이 과정은 단순함이 핵심입니다. 각각의 state는 "움직이는 조각"입니다. 그리고 **"움직이는 조각"은 적을수록 좋습니다**. 복잡한 건 버그를 일으키기 마련이기 때문입니다!
349+
다음으로 [`useState`](/reference/react/useState)를 사용하여 컴포넌트의 시각적 state를 표현해야 합니다. 이 과정은 단순함이 핵심입니다. 각각의 state는 "움직이는 조각"입니다. 그리고 **"움직이는 조각"은 적을수록 좋습니다**. 복잡한 건 버그를 일으키기 마련입니다!
350350
351-
먼저 *반드시 필요한* state를 가지고 시작해봅시다. 예를 들면 인풋의 `응답`은 반드시 저장해야 할 것입니다. 그리고 (존재한다면) 가장 최근에 발생한 `오류`도 저장해야 할 겁니다.
351+
먼저 *반드시 필요한* state를 가지고 시작해봅시다. 예를 들면 인풋의 `answer`은 반드시 저장해야 할 것입니다. 그리고 (존재한다면) 가장 최근에 발생한 `error`도 저장해야 할 겁니다.
352352
353353
```js
354354
const [answer, setAnswer] = useState('');
@@ -357,7 +357,7 @@ const [error, setError] = useState(null);
357357
358358
그리고 나서는 앞서 필요하다고 나열했던 나머지 시각적 state도 살펴봅시다. 보통은 어떤 state 변수를 사용할지에 대한 방법이 여러 가지기 때문에 이것저것 실험해볼 필요가 있습니다.
359359
360-
좋은 방법이 곧바로 떠오르지 않는다면 가능한 모든 시각적 state를 커버할 수 있는 *확실한* 것을 먼저 추가하는 방식으로 시작하세요:
360+
좋은 방법이 곧바로 떠오르지 않는다면 가능한 모든 시각적 state를 커버할 수 있는 *확실한* 것을 먼저 추가하는 방식으로 시작하세요.
361361
362362
```js
363363
const [isEmpty, setIsEmpty] = useState(true);

src/content/learn/sharing-state-between-components.md

+7-7
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ title: 컴포넌트 간 State 공유하기
44

55
<Intro>
66

7-
때때로 두 컴포넌트의 state가 항상 함께 변경되기를 원할 수 있습니다. 그렇게 하려면 각 컴포넌트에서 state를 제거하고 가장 가까운 공통의 부모 컴포넌트로 옮긴 후 props로 전달해야 합니다. 이 방법을 *State 끌어올리기*라고 하며 React 코드를 작성할 때 가장 흔히 하는 일 중 하나입니다.
7+
때때로 두 컴포넌트의 state가 항상 함께 변경되기를 원할 수 있습니다. 그렇게 하려면 각 컴포넌트에서 state를 제거하고 가장 가까운 공통 부모 컴포넌트로 옮긴 후 props로 전달해야 합니다. 이 방법을 *State 끌어올리기*라고 하며 React 코드를 작성할 때 가장 흔히 하는 일 중 하나입니다.
88

99
</Intro>
1010

@@ -96,8 +96,8 @@ h3, p { margin: 5px 0px; }
9696
두 패널을 조정하려면 다음 세 단계를 통해 부모 컴포넌트로 패널의 "State 끌어올리기"가 필요합니다.
9797
9898
1. 자식 컴포넌트의 state를 **제거**합니다.
99-
2. 하드 코딩된 값을 공통의 부모로부터 **전달**합니다.
100-
3. 공통의 부모에 state를 **추가**하고 이벤트 핸들러와 함께 전달합니다.
99+
2. 하드 코딩된 값을 공통 부모로부터 **전달**합니다.
100+
3. 공통 부모에 state를 **추가**하고 이벤트 핸들러와 함께 전달합니다.
101101
102102
이 방법으로 `Accordion` 컴포넌트가 두 `Panel`을 조정하고 한 번에 하나만 열리도록 할 수 있습니다.
103103
@@ -178,15 +178,15 @@ h3, p { margin: 5px 0px; }
178178

179179
상태 끌어올리기는 종종 state로 저장하고 있는 것의 특성을 바꿉니다.
180180

181-
이 케이스에서는, 한 번에 하나의 패널만 활성화되어야 합니다. 이를 위해 공통 부모 컴포넌트인 `Accordian`*어떤* 패널이 활성화된 패널인지 추적하고 있어야 합니다. state 변수에 `boolean` 값을 사용하는 대신, 활성화되어있는 `Panel`의 인덱스 숫자를 사용할 수 있습니다:
181+
이 케이스에서는, 한 번에 하나의 패널만 활성화되어야 합니다. 이를 위해 공통 부모 컴포넌트인 `Accordian`*어떤* 패널이 활성화된 패널인지 추적하고 있어야 합니다. state 변수에 `boolean` 값을 사용하는 대신, 활성화되어있는 `Panel`의 인덱스 숫자를 사용할 수 있습니다.
182182

183183
```js
184184
const [activeIndex, setActiveIndex] = useState(0);
185185
```
186186

187187
`activeIndex``0`이면 첫 번째 패널이 활성화된 것이고, `1`이면 두 번째 패널이 활성화된 것입니다.
188188

189-
`Panel`에서 "Show 버튼을 클릭하면 `Accordion`의 활성화된 인덱스를 변경해야 합니다. `activeIndex` state는 `Accordion` 내에서 정의되었기 때문에 `Panel`은 값을 직접 설정할 수 없습니다. `Accordion` 컴포넌트는 `Panel` 컴포넌트가 state를 변경할 수 있음을 [이벤트 핸들러를 prop으로 전달하기](/learn/responding-to-events#passing-event-handlers-as-props)를 통해 *명시적으로 허용*해야 합니다.
189+
`Panel`에서 "Show" 버튼을 클릭하면 `Accordion`의 활성화된 인덱스를 변경해야 합니다. `activeIndex` state는 `Accordion` 내에서 정의되었기 때문에 `Panel`은 값을 직접 설정할 수 없습니다. `Accordion` 컴포넌트는 `Panel` 컴포넌트가 state를 변경할 수 있음을 [이벤트 핸들러를 prop으로 전달하기](/learn/responding-to-events#passing-event-handlers-as-props)를 통해 *명시적으로 허용*해야 합니다.
190190

191191
```js
192192
<>
@@ -272,7 +272,7 @@ h3, p { margin: 5px 0px; }
272272
273273
<Diagram name="sharing_state_parent" height={385} width={487} alt="Accordion이라는 이름의 하나의 부모와 Panel이라는 이름의 두 자식으로 구성된 세 컴포넌트 트리를 나타내는 다이어그램입니다. Accordion은 값이 0인 activeIndex를 가지며, 첫 번째 패널의 isActive에 true를, 두 번째 패널의 isActive에 false를 반환합니다." >
274274
275-
처음에 `Accordion`의 `activeIndex`는 0이고, 따라서 첫 번째 `Panel`은 `isActive = true`를 받습니다.
275+
처음에 `Accordion`의 `activeIndex`는 `0`이므로 첫 번째 `Panel`은 `isActive = true`를 받습니다.
276276
277277
</Diagram>
278278
@@ -617,4 +617,4 @@ export const foods = [{
617617
618618
</Solution>
619619
620-
</Challenges>
620+
</Challenges>

0 commit comments

Comments
 (0)