Untitled

πŸ˜‰ ν—·κ°ˆλ Έλ˜ & λͺ°λžλ˜ λΆ€λΆ„λ“€λ§Œ μ •λ¦¬ν•˜λŠ” λ‚˜λ§Œμ˜ TIL
😯 λͺ¨λ“  κ°•μ˜ λ‚΄μš©μ€ 적지 μ•Šμ•„μš”!

였늘의 μ†Œκ°μ€?
μŠ€ν† λ¦¬λ³΄λ“œ 정말 정말 정말 λ„ˆλ¬΄ λ§˜μ— λ“€μ–΄μš”
μ»΄ν¬λ„ŒνŠΈλ₯Ό μ‹œκ°μ μΈ μš”μ†Œλ‘œ λ°”λ‘œ 확인할 수 μžˆλ‹€λ‹ˆ..
이걸 μ™œ 이제 μ•Œμ•˜μ„κΉŒμš”?

μŠ€ν† λ¦¬λ³΄λ“œλŠ” λ”°λ‘œ μ •λ¦¬ν–ˆμŠ΅λ‹ˆλ‹€.




[1] μ»΄ν¬λ„ŒνŠΈ μŠ€νƒ€μΌλ§

λ¦¬μ—‘νŠΈ μ»΄ν¬λ„ŒνŠΈμ— μŠ€νƒ€μΌμ„ μ μš©ν•˜λŠ” λ°©λ²•μ—λŠ” 3가지가 μžˆμŠ΅λ‹ˆλ‹€.

  1. μŠ€νƒ€μΌ μ‹œνŠΈ 이용
  2. Inline style 적용
  3. CSS in JS


[1-1] μŠ€νƒ€μΌ μ‹œνŠΈ 이용

import "./Box.css"; // ν•΄λ‹Ή λ°©μ‹μœΌλ‘œ λΆˆλŸ¬μ™€μ„œ μ μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

const Box = () => {
  return <div className="box" />;
};

export default Box;


[1-2] Inline Style 적용


const Box = ({ bgColor }) => {
  return <div className="box" style={{ backgroundColor: bgColor }} />;
};

export default Box;


[1-3] CSS in JS

ν•΄λ‹Ή 방법은 emotion 라이브러리λ₯Ό μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

npm install --save @emotion/react
npm install --save @emotion/styled

// ---> 두 방식이 λ‹€λ¦…λ‹ˆλ‹€. μ‚¬μš©μ— 따라 μ„€μΉ˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
npm install --save @emotion/babel-plugin

emotion λΌμ΄λΈŒλŸ¬λ¦¬λŠ” CSSλ₯Ό JS의 ν˜•νƒœλ‘œ μž‘μ„±ν•  수 있게 ν•΄μ€λ‹ˆλ‹€.

/** @jsxImportSource @emotion/react */ // ν”„λž˜κ·Έλ§ˆλ₯Ό λΆ™μ—¬μ€λ‹ˆλ‹€.
import "./App.css";
import Box from "./components/Box";
import { css } from "@emotion/react";

const style = css`
  color: hotpink;
`;

const SomeComponent = ({ children }) => (
  <div css={style}>Some Hotpink text! {children}</div>
);

function App() {
  return (
    <div>
      <SomeComponent />
      <Box />
    </div>
  );
}

export default App;

create-react-appμ—μ„œλŠ” ν”„λž˜κ·Έλ§ˆλ₯Ό λΆ™μ—¬μ£ΌλŠ” λŒ€μ‹  .babelrc νŒŒμΌμ„ λ§Œλ“€μ–΄λ„ 적용이 λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

λ”°λΌμ„œ νŠΉλ³„ν•œ 방법을 μ‚¬μš©ν•΄μ•Ό ν•©λ‹ˆλ‹€.


κ·Έ 쀑 ν•˜λ‚˜μ˜ λ°©λ²•μœΌλ‘œ craco 라이브러리λ₯Ό μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

cracoλŠ” create-react-app-config-overrideλ₯Ό 쀄인 말이라고 ν•©λ‹ˆλ‹€.

npm install --save @craco/craco
npm install --save @emotion/babel-preset-css-prop


  • craco.config.js
module.exports = {
  babel: {
    presets: ["@emotion/babel-preset-css-prop"],
  },
};
  • package.json
"scripts": {
  "start": "craco start",
  "build": "craco build",
  "test": "craco test"
},


λ‹€μ‹œ npm start λͺ…λ Ήμ–΄λ‘œ μ‹€ν–‰ν•˜λ©΄ μŠ€νƒ€μΌμ΄ 잘 μ μš©λ˜λŠ” 것을 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

Untitled 1




[2] useMemo ν›…

useMemoλŠ” μ΅œμ ν™”λ₯Ό μœ„ν•œ ν›…μž…λ‹ˆλ‹€.

λ¦¬μ—‘νŠΈ μ»΄ν¬λ„ŒνŠΈλ₯Ό κ΅¬ν˜„ν•  λ•Œ ν•¨μˆ˜λ‘œ κ΅¬ν˜„ν•©λ‹ˆλ‹€.

λ”°λΌμ„œ ν•΄λ‹Ή μ»΄ν¬λ„ŒνŠΈκ°€ λžœλ”λ§ λœλ‹€λŠ” 것은, λˆ„κ΅°κ°€κ°€ ν•΄λ‹Ή ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•΄μ„œ μ‹€ν–‰μ‹œν‚¨λ‹€λŠ” μ˜λ―Έμ™€ λ™μΌν•©λ‹ˆλ‹€.


κ·Έλ ‡λ‹€λ©΄ ν•΄λ‹Ή ν•¨μˆ˜λŠ” μ–Έμ œ λ‹€μ‹œ λ¦¬λ Œλ”λ§ λ κΉŒμš”?

  1. μžμ‹ μ˜ μƒνƒœκ°€ 변경될 λ•Œ
  2. λΆ€λͺ¨ μ»΄ν¬λ„ŒνŠΈλ‘œλΆ€ν„° λ°›λŠ” prop이 변경될 λ•Œ
  3. λΆ€λͺ¨ μ»΄ν¬λ„ŒνŠΈμ˜ μƒνƒœκ°€ 변경될 λ•Œ


μ΄λŸ¬ν•œ λ¦¬λ Œλ”λ§ μž‘μ—… μ‹œ ν•¨μˆ˜ λ‚΄λΆ€ μ—°μ‚° 속도가 느린 μ»΄ν¬λ„ŒνŠΈλΌλ©΄ κ½€ λ§Žμ€ μ„±λŠ₯을 μ†ŒλΉ„ν•˜κ²Œ λ©λ‹ˆλ‹€.

λ”°λΌμ„œ useMemo 훅을 μ‚¬μš©ν•΄μ„œ μ΅œμ ν™”λ₯Ό 진행할 수 μžˆμŠ΅λ‹ˆλ‹€.

const result = useMemo(() => sum(n), [n]);
// n의 값이 λ³€κ²½λ˜μ—ˆμ„ λ•Œλ§Œ sum ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•΄μ„œ 연산을 μ§„ν–‰ν•©λ‹ˆλ‹€.




[3] React.memo

λΆ€λͺ¨ μ»΄ν¬λ„ŒνŠΈμ˜ μƒνƒœκ°€ 변경될 λ•Œ λ¦¬λ Œλ”λ§μ΄ λ˜λŠ” 것을 막기 μœ„ν•΄ React.memo ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

import React from "react";
import "./Box.css";

// λ‹¨μˆœνžˆ React.memo둜 κ°μ‹Έλ§Œ μ€˜λ„ λ¦¬λ Œλ”λ§μ„ 막을 수 μžˆμŠ΅λ‹ˆλ‹€!
const Box = React.memo(() => {
  console.log("Render Box!");
  return <div className="box"></div>;
});

export default Box;




[4] useCallback ν›…

ν•¨μˆ˜κ°€ λ‹€μ‹œ μ •μ˜λ˜λŠ” 것을 막기 μœ„ν•΄ useCallback 훅을 μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

React.memoλ₯Ό μ‚¬μš©ν•΄μ„œ μ •μ˜ν•œ Checkbox μ»΄ν¬λ„ŒνŠΈλ₯Ό μ—¬λŸ¬κ°œ μ‚¬μš©ν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

// App.js
function App() {
  const [foodOn, setFoodOn] = useState(false);
  const [clothesOn, setclothesOn] = useState(false);
  const [shelterOn, setShelterOn] = useState(false);

  const foodChange = (e) => setFoodOn(e.target.checked);
  const clothesChange = (e) => setclothesOn(e.target.checked);
  const shelterChange = (e) => setShelterOn(e.target.checked);

  return (
    <div>
      <Checkbox label="Food" on={foodOn} onChange={foodChange} />
      <Checkbox label="Clothes" on={clothesOn} onChange={clothesChange} />
      <Checkbox label="Shelter" on={shelterOn} onChange={shelterChange} />
    </div>
  );
}

food Checkbox의 값이 변해도 λ‹€λ₯Έ μ²΄ν¬λ°•μŠ€κΉŒμ§€ λͺ¨λ‘ μž¬μ •μ˜λ˜λŠ” 것을 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

λ”°λΌμ„œ 이럴 λ•Œ useCallback으둜 ν•¨μˆ˜λ₯Ό κ°μ‹Έμ€λ‹ˆλ‹€.

const foodChange = useCallback((e) => setFoodOn(e.target.checked), []);
const clothesChange = useCallback((e) => setclothesOn(e.target.checked), []);
const shelterChange = useCallback((e) => setShelterOn(e.target.checked), []);
// useMemo와 λ™μΌν•˜κ²Œ λ‘λ²ˆμ§Έ νŒŒλΌλ―Έν„°λ‘œ μ§€μΌœλ³΄κ³  μžˆλ‹€κ°€
// ν•΄λ‹Ή 값이 변경될 λ•Œλ§Œ ν•¨μˆ˜ μž¬ν• λ‹Ήμ„ ν—ˆμš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.




[5] μ‚¬μš©μž μ •μ˜ ν›…

κΈ°μ‘΄ 훅듀을 μ‘°ν•©ν•΄μ„œ μ‚¬μš©μž μ •μ˜ ν›…μœΌλ‘œ λΉΌμ„œ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μ΄λŠ” 쀑볡 μ½”λ“œλ₯Ό μ œκ±°ν•  수 μžˆλ‹€λŠ” μž₯점이 μžˆμŠ΅λ‹ˆλ‹€.

μ‚¬μš©μž μ •μ˜ 훅은 hooks 디렉토리 내뢀에 μ •μ˜ν•©λ‹ˆλ‹€.

Untitled 2

// useToggle.js
import { useCallback, useState } from "react";

const useToggle = (initialState = false) => {
  const [state, setState] = useState(initialState);
  const toggle = useCallback(() => setState((state) => !state), []);

  return [state, toggle];
};

export default useToggle;
// App.js Component
// ...
const [on, toggle] = useToggle(); // state -> on

return (
  <div>
    <button onClick={toggle}>{on ? "True" : "False"}</button>
  </div>
);




[6] 둜그인, νšŒμ›κ°€μž… 폼

storybook으둜 μ‹€μŠ΅μ„ μ§„ν–‰ν–ˆμŠ΅λ‹ˆλ‹€.

Untitled 3

ν•˜λ‚˜μ”© λŠ˜μ–΄λ‚˜λŠ” μ»΄ν¬λ„ŒνŠΈλ₯Ό λ³Ό λ•Œ λ§ˆλ‹€ νŽΈμ•ˆν•΄μ§€λ„€μš”.. 😊





좜처

ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€

React.js Document

storybook Document

μΉ΄ν…Œκ³ λ¦¬: ,

μ—…λ°μ΄νŠΈ:

λŒ“κΈ€λ‚¨κΈ°κΈ°