diff --git a/June/article/4-React-Tips-to-Instantly-Improve-Your-Code.md b/June/article/4-React-Tips-to-Instantly-Improve-Your-Code.md
new file mode 100644
index 0000000..989eb6e
--- /dev/null
+++ b/June/article/4-React-Tips-to-Instantly-Improve-Your-Code.md
@@ -0,0 +1,365 @@
+# [4 React Tips to Instantly Improve Your Code](https://javascript.plainenglish.io/4-react-tips-to-instantly-improve-your-code-7456e028cfa3)
+
+Pavel Pogosov
+Updated On Feb 2, 2023, Translate on May 31 2024
+Keyword : **React**
+
+React에 대한 탄탄한 지식은 프론트엔드 개발자에게 가장 가치 있는 기술 중 하나입니다. 많은 기업들이 지속적으로 React 개발자를 찾고 있으며, 그들에게 더 많은 보수를 지불하려고 합니다. 그렇기 때문에 개발자로서 지속적으로 성장하는 것은 매우 보람 있는 일입니다.
+
+여러분의 여정에 도움이 되기 위해, 제가 더 나은 React 코드를 작성하는 데 도움이 되었던 네 가지 팁을 공유하고자 합니다. 새로운 것을 배우고 유용하게 사용하시길 바랍니다. 그럼 바로 시작해 봅시다!
+
+### 목차
+
+- 핸들러에서 함수 반환하기
+- 책임 분리
+- 조건문 대신 객체 맵 사용하기
+- React lifecycle의 외부에 독립 변수 두기
+
+### 핸들러에서 함수 반환하기
+
+함수형 프로그래밍에 익숙하다면 제가 무슨 말을 하는지 아실 겁니다. 우리는 이를 "[커링](https://en.wikipedia.org/wiki/Currying)"이라고 부를 수 있습니다. 본질적으로, 일부 함수 매개변수를 미리 설정하는 것입니다.
+
+아래 보일러플레이트 코드에서 명시적인 문제가 있습니다. 이 기술이 도움이 될 것입니다!
+
+```tsx
+export default function App() {
+ const [user, setUser] = useState({
+ name: "",
+ surname: "",
+ address: "",
+ });
+
+ // 첫 핸들러
+ const handleNameChange = (e) => {
+ setUser((prev) => ({
+ ...prev,
+ name: e.target.value,
+ }));
+ };
+
+ // 두번째 핸들러!
+ const handleSurnameChange = (e) => {
+ setUser((prev) => ({
+ ...prev,
+ surname: e.target.value,
+ }));
+ };
+
+ // 세번째 핸들러!!!
+ const handleAddressChange = (e) => {
+ setUser((prev) => ({
+ ...prev,
+ address: e.target.value,
+ }));
+ };
+
+ // 만약 하나의 input이 더 필요하다면 어떨까요? 이를 위한 또 다른 핸들러를 만들어야할까요?
+
+ return (
+ <>
+
+
+
+ >
+ );
+}
+```
+
+**Solution**
+
+```tsx
+export default function App() {
+ const [user, setUser] = useState({
+ name: "",
+ surname: "",
+ address: "",
+ });
+
+ const handleInputChange = (field) => {
+ return (e) => {
+ setUser((prev) => ({
+ ...prev,
+ [field]: e.target.value,
+ }));
+ };
+ };
+
+ return (
+ <>
+
+
+
+
+ {JSON.stringify(user)}
+ >
+ );
+}
+```
+
+https://medium.com/@pashkapag/5-react-usestate-mistakes-that-will-get-you-fired-b342289debfe
+
+### 책임 분리
+
+"God" 컴포넌트를 만드는 것은 개발자들이 흔히 저지르는 실수입니다. "God" 컴포넌트라고 불리는 이유는 이해하고 유지 보수하기 어려운 많은 코드 라인을 포함하고 있기 때문입니다. 독립적인 하위 모듈 세트로 컴포넌트를 나누는 것을 강력히 권장합니다.
+
+일반적인 구조는 다음과 같습니다:
+
+- **UI 모듈**: 시각적 표현만 담당합니다.
+- **로직/모델 모듈**: 비즈니스 로직만 포함합니다. 예를 들어, 커스텀 훅이 여기에 해당합니다.
+- **Lib 모듈**: 컴포넌트에 필요한 모든 유틸리티를 포함합니다.
+
+이 개념을 설명하기 위한 작은 데모 예제를 보여드리겠습니다.
+
+```tsx
+export function ListComponent() {
+ // Our local state
+ const [list, setList] = useState([]);
+
+ // 서버로부터 데이터를 로드하기위한 핸들러
+ const fetchList = async () => {
+ try {
+ const resp = await fetch("https://www.url.com/list");
+ const data = await resp.json();
+
+ setList(data);
+ } catch {
+ showAlert({ text: "Something went wrong!" });
+ }
+ };
+
+ // 마운트될 때만 fetch하길 원하기에
+ useEffect(() => {
+ fetchList();
+ }, []);
+
+ // 아이템을 지우는 역할의 핸들러
+ const handleDeleteItem = (id) => {
+ return () => {
+ try {
+ fetch(`https://www.url.com/list/${id}`, {
+ method: "DELETE",
+ });
+ setList((prev) => prev.filter((x) => x.id !== id));
+ } catch {
+ showAlert({ text: "Something went wrong!" });
+ }
+ };
+ };
+
+ // 여기서 데이터 아이템을 render한다
+ return (
+
+ {list.map(({ id, name }) => (
+
+ {/* We want to trim long name with ellipsis */}
+ {name.slice(0, 30) + (name.length > 30 ? "..." : "")}
+
+
+ );
+}
+```
+
+### 조건문 대신 객체 맵 사용하기
+
+변수에 따라 다양한 요소를 표시해야 할 경우, 이 팁을 구현할 수 있습니다. 이 간단한 전략을 사용하면 컴포넌트를 더 선언적으로 만들고 코드 이해를 단순화할 수 있습니다. 게다가 기능을 확장하는 것도 더 쉬워집니다.
+
+**Problem**
+
+```tsx
+function Account({ type }) {
+ let Component = UsualAccount;
+
+ if (type === "vip") {
+ Component = VipAccount;
+ }
+
+ if (type === "moderator") {
+ Component = ModeratorAccount;
+ }
+
+ if (type === "admin") {
+ Component = AdminAccount;
+ }
+
+ return (
+
+ );
+}
+```
+
+[링크](http://javascript.plainenglish.io/frontend-architectures-classic-approach-no-architecture-d3c839e46403?source=post_page-----7456e028cfa3--------------------------------)
+
+### React lifecycle의 외부에 독립 변수 두기
+
+아이디어는 React 컴포넌트 생명주기 메서드를 필요로 하지 않는 로직을 컴포넌트 자체에서 분리하는 것입니다. 이렇게 하면 종속성을 더 명확하게 만들어 코드의 명확성을 향상시킵니다. 따라서 컴포넌트를 읽고 이해하는 것이 훨씬 쉬워집니다.
+
+**Problem**
+
+```tsx
+function useItemsList() {
+ const defaultItems = [1, 2, 3, 4, 5];
+ const [items, setItems] = useState(defaultItems);
+
+ const toggleArrayItem = (arr, val) => {
+ return arr.includes(val) ? arr.filter((el) => el !== val) : [...arr, val];
+ };
+
+ const handleToggleItem = (num) => {
+ return () => {
+ setItems(toggleArrayItem(items, num));
+ };
+ };
+
+ return {
+ items,
+ handleToggleItem,
+ };
+}
+```
+
+**Solution**
+
+```tsx
+const DEFAULT_ITEMS = [1, 2, 3, 4, 5];
+
+const toggleArrayItem = (arr, val) => {
+ return arr.includes(val) ? arr.filter((el) => el !== val) : [...arr, val];
+};
+
+function useItemsList() {
+ const [items, setItems] = useState(DEFAULT_ITEMS);
+
+ const handleToggleItem = (num) => {
+ return () => {
+ setItems(toggleArrayItem(items, num));
+ };
+ };
+
+ return {
+ items,
+ handleToggleItem,
+ };
+}
+```
+
+**Thanks for reading!**
diff --git a/June/article/When-do-I-use-functions-in-a-Hooks-Dependency-Array?.md b/June/article/When-do-I-use-functions-in-a-Hooks-Dependency-Array?.md
new file mode 100644
index 0000000..fb484cc
--- /dev/null
+++ b/June/article/When-do-I-use-functions-in-a-Hooks-Dependency-Array?.md
@@ -0,0 +1,260 @@
+# [When do I use functions in a Hooks Dependency Array?](https://reacttraining.com/blog/when-to-use-functions-in-hooks-dependency-array)
+
+Brad Westfall
+Updated On Sep 30, 2019, Translate on Jun 3, 2024
+Keyword : **React** **Hooks**
+
+### 간단히 말하자면...
+
+**linter가 당신에게 그렇게 하라고 할때마다 해야합니다.**
+[그리고 이것은 꽤 자주 일어납니다.](https://legacy.reactjs.org/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of-dependencies)
+하지만 왜 linter는 때때로 그렇게 하라고 하고, 항상 그렇지는 않을까요?
+
+---
+
+Hooks는 React에 함수형 구성을 도입하기 위해 설계되었지만, 제대로 작동하기 위해 따라야 할 몇 가지 규칙이 있습니다. React에는 특정 작업을 잘못할 때(예: 훅의 순서를 조건부로 변경하는 경우) 알려주는 몇 가지 내장 린팅 규칙이 있습니다. [또한 별도로 설치해야 하는 추가 규칙도 있습니다.](https://www.npmjs.com/package/eslint-plugin-react-hooks) 이러한 추가 규칙은 의존성 배열에 무엇을 추가해야 하는지 알려주는 [exhaustive-deps](https://github.com/facebook/react/issues/14920) 규칙과 같이 버그를 조기에 잡는 데 도움이 됩니다.
+
+의존성 배열 개념을 사용하는 훅은 여러 가지가 있지만, 아마도 많은 사람들이 처음 배우는 훅 중 하나인 useEffect를 배우면서 의존성 배열에 대해 알게 될 것입니다:
+
+```jsx
+function ComposeMessage() {
+ const [message, setMessage] = useState();
+
+ // 메시지가 변경될 때마다 제목을 변경하는 것은 side-effects입니다.
+ // 그래서 `useEffect`가 필요합니다.
+ useEffect(() => {
+ document.title = message;
+ }, [message]);
+
+ return (
+
+ setMessage(e.target.value)} />
+
+ );
+}
+```
+
+우리의 effect는 message 상태에 "의존"합니다. 따라서 그 상태가 변경되면 effect를 다시 실행해야 합니다.
+
+이제 메시지가 변경될 때 메시지를 로컬 저장소에 저장해 보겠습니다. 이렇게 하면 메시지가 저장되지 않았을 때 신속하게 초안으로 복구할 수 있습니다. 또한 수신자의 사용자 ID를 나타내는 uid prop도 사용하겠습니다.
+
+```jsx
+import { saveToLocalStorage, getFromLocalStorage } from "./saveToLocalStorage";
+
+function ComposeMessage({ uid }) {
+ const [message, setMessage] = useState(getFromLocalStorage(uid) || "");
+
+ useEffect(() => {
+ saveToLocalStorage(uid, message);
+ }, [uid, message]); // 우리의 effect는 이제 더 많은 것에 의존하고 있습니다.
+
+ return (
+ setMessage(e.target.value)}
+ />
+ );
+}
+```
+
+linter는 이제 uid가 side effect의 일부이기 때문에 의존성 배열에 uid를 추가하라고 요청할 것입니다.
+
+> 그러나 'uid'는 상태가 아닌 props 입니다 !
+
+자, 괜찮습니다. 비록 그것이 우리의 컴포넌트 상태는 아니지만, 다른 곳(예: 부모 컴포넌트)의 상태이므로 동일한 개념입니다.
+
+그렇다면 함수 `saveToLocalStorage`는 어떻게 할까요? effect에서 이를 사용하고 있으니 의존성 배열에 추가해야 할까요?
+
+이 경우에는 아닙니다. 왜 그런지 논의하기 전에, `saveToLocalStorage`가 prop으로 전달되는 아래의 리팩터링된 코드와 비교해 봅시다.
+
+```jsx
+function ComposeMessage({ uid, defaultMessage, saveToLocalStorage }) {
+ const [message, setMessage] = useState(defaultMessage || "");
+
+ useEffect(() => {
+ saveToLocalStorage(uid, message);
+ }, [uid, message, saveToLocalStorage]); // Now it goes here
+
+ return (
+ setMessage(e.target.value)}
+ />
+ );
+}
+```
+
+이제 linter가 saveToLocalStorage를 의존성 배열에 추가하라고 요청합니다. 차이점은 무엇일까요?
+
+궁극적으로, React는 effects 내의 상태가 변경될 경우 effect를 "re-run" 해야 합니다. 이전에 `saveToLocalStorage`가 import 되었을 때, linter는 그 함수가 컴포넌트 상태를 "close over"하여 변경되었을 때 effect를 다시 실행할 필요가 없다는 것을 알고 있습니다. 그러나 `saveToLocalStorage`가 prop일 때, 린터는 부모 컴포넌트가 `ComposeMessage`를 어떻게 구현할지에 대해 충분히 알지 못합니다. 다시 말해, linter는 전체 앱을 탐색하여 `ComposeMessage`가 사용되는 모든 위치와 부모가 prop을 전달하는 방식을 알지 못합니다. 그리고 설령 그렇게 한다 하더라도, linter는 당신이 미래에 그것을 어떻게 사용할지 의도를 알지 못합니다. 이러한 불확실성 때문에, 린터는 이제 `saveToLocalStorage`를 의존성 배열에 추가하라고 요청합니다.
+
+다음은 부모 컴포넌트가 구현될 수 있는 한 가지 예입니다:
+
+```jsx
+import { saveToLocalStorage, getFromLocalStorage } from "./saveToLocalStorage";
+
+function UserProfile({ uid }) {
+ return (
+
+ );
+}
+```
+
+비록 `saveToLocalStorage`가 여전히 import에 대한 참조일 뿐이지만, 자식 `ComposeMessage`는 prop이 의존성 배열에 추가되어야 한다고 말하고 있습니다. 다시 말하지만, 이제 중요한 차이점은 **확실성**입니다. 이전에는 React가 `saveToLocalStorage`가 어떤 상태도 close over하지 않는다는 것을 알고 있었습니다. 부모를 리팩터링한다면 어떻게 될까요?
+
+부모 컴포넌트에 애플리케이션 세부 정보를 유지하고 `ComposeMessage`는 저장해야 할 시점만 보고하고 `uid`와 같은 것에 대해 알 필요가 없다고 가정해 봅시다. 이 경우 코드가 다음과 같이 보일 수 있습니다:
+
+```jsx
+// UserProfile.js
+import ComposeMessage from "./ComposeMessage";
+import { saveToLocalStorage, getFromLocalStorage } from "./saveToLocalStorage";
+
+function UserProfile({ uid }) {
+ return (
+ saveToLocalStorage(uid, message)}
+ />
+ );
+}
+
+// ComposeMessage.js
+function ComposeMessage({ defaultMessage, saveToLocalStorage }) {
+ const [message, setMessage] = useState(defaultMessage || "");
+
+ useEffect(() => {
+ saveToLocalStorage(message);
+ }, [message, saveToLocalStorage]);
+
+ return (
+ setMessage(e.target.value)}
+ />
+ );
+}
+```
+
+저장하기 위해 실제 함수로 전달되는 `saveToLocalStorage`는 import된 `saveToLocalStorage`를 래핑하는 화살표 함수입니다. 이 리팩터링을 통해 전달된 함수는 `uid`를 close over하게 되므로, 이제 변경될 가능성이 있기 때문에 `ComposeMessage`에서 `saveToLocalStorage` prop을 의존성 배열에 포함하는 것이 중요합니다. React는 이 함수가 필요할지 여부를 알 수 없으므로 항상 포함시키도록 했습니다.
+
+다른 고려 사항:
+
+부모 컴포넌트가 어떤 이유로든 다시 렌더링되면(예: 상태 변경 또는 새로운 props), 화살표 함수는 다시 렌더링될 때마다 새로 생성됩니다. 이는 부모가 다시 렌더링될 때마다 `saveToLocalStorage` prop의 함수 아이덴티티가 변경된다는 것을 의미합니다. `ComposeMessage`에서는 `saveToLocalStorage`를 의존성 배열에 포함시켜 버그를 방지해야 하지만, 부모가 다시 렌더링될 때마다 그 아이덴티티가 변경되므로 불필요하게 로컬 저장소에 저장하게 됩니다. 이를 [시연하는 예제](https://codesandbox.io/s/funny-taussig-5tont)를 보세요.
+
+로컬 저장소에 너무 자주 저장하는 것은 괜찮을 수 있지만, side effect가 네트워크 요청인 경우에는 이를 피하고 싶을 것입니다. 따라서 함수의 아이덴티티가 변하지 않도록 유지할 필요가 있습니다.
+
+### `useCallback` 사용하기
+
+`uid`와 함수의 아이덴티티를 동기화하기 위해 부모 컴포넌트의 함수를 다음과 같이 구현할 수 있습니다:
+
+```jsx
+import ComposeMessage from "./ComposeMessage";
+import { saveToLocalStorage, getFromLocalStorage } from "./saveToLocalStorage";
+
+function UserProfile({ uid }) {
+ const save = useCallback(
+ (message) => {
+ saveToLocalStorage(uid, message);
+ },
+ [uid]
+ );
+
+ return (
+
+ );
+}
+```
+
+`useCallback` 훅은 이와 같은 목적을 위해 함수의 메모이제이션 버전을 생성합니다. 이는 또 다른 의존성 배열 개념을 가진 훅입니다. 이 경우 `save` 함수는 의존성 배열 내의 무언가가 변경되지 않는 한, `UserProfil`e이 몇 번이나 다시 렌더링되더라도 동일한 아이덴티티를 유지합니다. 유일한 예외는 의존성 배열의 무언가가 변경될 때 새로운 아이덴티티가 생성되는 것입니다.
+
+시나리오를 통해 설명해 보겠습니다:
+
+- 부모 컴포넌트 `UserProfile`이 `ComposeMessage`에 함수 prop을 전달합니다.
+- `ComposeMessage`에서 효과(effect)를 다시 실행시키는 두 가지 조건은 다음과 같습니다:
+
+ - 메시지가 변경될 때 (우리가 원하는 것)
+ - 또는 `saveToLocalStorage` prop이 변경될 때 (이 점을 염두에 두세요)
+
+- 부모 함수는 리렌더링을 경험할 수 있으며 이는 `ComposeMessage`를 다시 렌더링하게 합니다. 이 경우 useEffect의 의존성 배열이 다시 평가됩니다. 부모가 다시 렌더링되지만 `uid`가 변경되지 않는 경우, `saveToLocalStorage` 함수가 변경되지 않도록 하여 effect가 실행되지 않도록 해야 합니다. `useCallback`이 이를 해결해줍니다.
+- 부모의 `uid`가 변경되면, `useCallback`은 `save`를 위한 새로운 아이덴티티를 생성하고, 따라서 `uid`가 변경될 때 이후의 effect가 다시 실행됩니다.
+
+## 요약
+
+따라서 함수가 의존성 배열에 포함되어야 하는 경우는 언제일까요? 상태를 잠재적으로 close over 할 수 있을 때입니다.
+
+이 예제가 이를 완벽하게 요약해 줍니다:
+
+```jsx
+const MyComponent = () => {
+ // 이 함수는 이 순간에 state를 close over하지 않습니다.
+ function logData() {
+ console.log("logData");
+ }
+
+ useEffect(() => {
+ logData();
+ }, []); // `logData`는 의존성 배열 안으로 들어가지 않아도 됩니다.
+
+ // ...
+};
+```
+
+그렇다면 어떤 props를 `console.log` 해봅시다.
+
+```jsx
+const MyComponent = ({ data }) => {
+ // 이 함수는 이제 상태를 close over 합니다.(props는 어떤 것의 상태임을 기억하세요)
+ function logData() {
+ console.log(data);
+ }
+
+ useEffect(() => {
+ logData();
+ }, [logData]); // 이제 이것을 여기에 추가하세요
+
+ // ...
+};
+```
+
+이제 `logData`가 의존성 배열에 포함되었으므로, 새로운 문제는 `MyComponent`가 리렌더링될 때마다 이 함수가 변경된다는 점입니다. 따라서 `useCallback`을 사용해야 합니다:
+
+```jsx
+const MyComponent = ({ data }) => {
+ const logData = useCallback(() => {
+ console.log(data);
+ }, [data]);
+
+ useEffect(() => {
+ logData();
+ }, [logData]); // 이제 이것을 여기에 추가하세요
+
+ // ...
+};
+```
+
+또는 이렇게 할 수 있습니다.
+
+```jsx
+const MyComponent = ({ data }) => {
+ useEffect(() => {
+ function logData() {
+ console.log(data);
+ }
+ logData();
+ }, [data]); // 이제 오직 `data`만 이것에 필요합니다.
+
+ // ...
+};
+```
+
+`logData`는 상태를 close over하지만, 그것 자체가 effect의 일부이므로 배열에는 `data`만 필요합니다.