๐ก๐ก๐ก๐ก๐ก๐ก๐ก๐ก๐ก๐ก๐ก๐ก๐ก๐ก๐ก๐ก๐ก๐ก๐ก๐ก๐ก๐ก
๋ช ๊ฐ์ง ์ง์นจ์ ์ ๊ณตํ๊ธฐ ์ํด ์ด ๊ฒ์๋ฌผ์ ๋๊ธ์ ๋ถ์ํ์ต๋๋ค: https://github.com/facebook/react/issues/14920#issuecomment -471070149.
๐ก๐ก๐ก๐ก๐ก๐ก๐ก๐ก๐ก๐ก๐ก๐ก๐ก๐ก๐ก๐ก๐ก๐ก๐ก๐ก๐ก๐ก
์ด๊ฒ์ useEffect
์ ๊ฐ์ Hooks์ ๋ํ ์ข
์์ฑ ๋ชฉ๋ก์ ํ์ธํ๋ ์๋ก์ด ESLint ๊ท์น์ผ๋ก, ์ค๋๋ ํด๋ก์ ํจ์ ์ผ๋ก๋ถํฐ ๋ณดํธํฉ๋๋ค. ๋๋ถ๋ถ์ ๊ฒฝ์ฐ ์๋ ์์ ์ด ์์ต๋๋ค. ๋ค์ ์ฃผ์ ๋ ๋ง์ ๋ฌธ์๋ฅผ ์ถ๊ฐํ ์์ ์
๋๋ค.
yarn add eslint-plugin-react-hooks<strong i="18">@next</strong>
# or
npm install eslint-plugin-react-hooks<strong i="19">@next</strong>
ESLint ๊ตฌ์ฑ:
{
"plugins": ["react-hooks"],
// ...
"rules": {
"react-hooks/rules-of-hooks": 'error',
"react-hooks/exhaustive-deps": 'warn' // <--- THIS IS THE NEW RULE
}
}
๊ท์น์ด ์๋ํ๋์ง ํ์ธํ๋ ๊ฐ๋จํ ํ ์คํธ ์ฌ๋ก:
function Foo(props) {
useEffect(() => {
console.log(props.name);
}, []); // <-- should error and offer autofix to [props.name]
}
์ด ์๋ก์ด react-hooks/exhaustive-deps
๋ฆฐํธ ๊ท์น์ด ์คํ๋์ง๋ง ์ฝ๋๊ฐ ์ ํํ๋ค๊ณ ์๊ฐ ๋๋ฉด ์ด ํธ์ ๊ฒ์ํ์ญ์์ค.
๋ค์ ์ธ ๊ฐ์ง๋ฅผ ํฌํจ ํ์ญ์์ค .
๋น์ ์๊ฒ๋ ๊ฐ๋จํ ์๋ ์์ง๋ง ์ฐ๋ฆฌ์๊ฒ๋ ์ ํ ๊ฐ๋จํ์ง ์์ต๋๋ค. ๊ทํ์ ์๊ฒฌ์ ๋ ์ค ํ๋๊ฐ ํฌํจ๋์ง ์์ ๊ฒฝ์ฐ(์: CodeSandbox ๋งํฌ ์์), ๊ทธ๋ ์ง ์์ผ๋ฉด ํ ๋ก ์ ์ถ์ ํ๊ธฐ๊ฐ ๋งค์ฐ ์ด๋ ต๊ธฐ ๋๋ฌธ์
์ด ์ค๋ ๋์ ์ต์ข ๋ชฉํ๋ ์ผ๋ฐ์ ์ธ ์๋๋ฆฌ์ค๋ฅผ ์ฐพ์ ๋ ๋์ ๋ฌธ์ ๋ฐ ๊ฒฝ๊ณ ๋ก ๋ณํํ๋ ๊ฒ์ ๋๋ค. ์ด๋ ์ถฉ๋ถํ ์ธ๋ถ ์ ๋ณด๋ฅผ ์ฌ์ฉํ ์ ์๋ ๊ฒฝ์ฐ์๋ง ๋ฐ์ํ ์ ์์ต๋๋ค. ๋ถ์์ ํ ์ฝ๋ ์กฐ๊ฐ์ด ํฌํจ๋ ๋๋ผ์ด๋ธ ๋ฐ์ด ์ฃผ์์ ํ ๋ก ์ ์ง์ ํฌ๊ฒ ๋จ์ด๋จ๋ฆฌ๋ฉฐ ๊ฐ์น๊ฐ ์์ ์ ๋๋ก ๋จ์ด์ง๋๋ค.
์ด ์์๋ ๋ต์ฅ์ด ์์ต๋๋ค. https://github.com/facebook/react/issues/14920#issuecomment -466145690
์ด๊ฒ์ defaultIndeterminate
์ํ์ ์ฌ์ฉํ์ฌ ์ด๊ธฐ ๋ ๋๋ง์์ ๋ถํ์คํ ์ํ๋ฅผ ์ค์ ํ๋ ์ ์ด๋์ง ์๋ Checkbox ๊ตฌ์ฑ ์์์
๋๋ค( indeterminate
์์ ์์ฑ์ด ์๊ธฐ ๋๋ฌธ์ ref๋ฅผ ์ฌ์ฉํ๋ JS์์๋ง ์ํํ ์ ์์). ์ด ์ํ์ defaultValue
์ฒ๋ผ ์๋ํ๋๋ก ๋์ด ์์ผ๋ฉฐ, ์ฌ๊ธฐ์ ํด๋น ๊ฐ์ ์ด๊ธฐ ๋ ๋๋ง์์๋ง ์ฌ์ฉ๋ฉ๋๋ค.
๊ท์น์ defaultIndeterminate
๊ฐ ์ข
์์ฑ ๋ฐฐ์ด์์ ๋๋ฝ๋์๋ค๊ณ ๋ถํํ์ง๋ง ์ด๋ฅผ ์ถ๊ฐํ๋ฉด ์ ๊ฐ์ด ์ ๋ฌ๋๋ ๊ฒฝ์ฐ ๊ตฌ์ฑ ์์๊ฐ ์ ์ด๋์ง ์์ ์ํ๋ฅผ ์๋ชป ๋ฎ์ด์ฐ๊ฒ ๋ฉ๋๋ค. ์ข
์์ฑ ๋ฐฐ์ด์ prop์ ์ํด ์์ ํ ์ ์ด๋์ง ์๋ ์ํ๊ฐ ๋๊ธฐ ๋๋ฌธ์ ์์ ํ ์ ๊ฑฐํ ์ ์์ต๋๋ค.
์ด๊ฒ๊ณผ ๊ท์น์ด ์ก์์ผ ํ๋ ๊ฒฝ์ฐ์ ์ ํ์ ๊ตฌ๋ณํ ์ ์๋ ๋ฐฉ๋ฒ์ ์์ง๋ง ์ต์ข ๊ท์น ๋ฌธ์์ ์ ์๋ ํด๊ฒฐ ๋ฐฉ๋ฒ์ด ํฌํจ๋ ์ ์๋ค๋ฉด ์ข์ ๊ฒ์ ๋๋ค. ๐
์ฌ: https://github.com/facebook/react/issues/14920#issuecomment -466144466
@billyjanitsch ๋์ ์๋ํ ๊น์? https://codesandbox.io/s/jpx1pmy7ry
defaultIndeterminate
์ด๊ธฐํ๋๋ indeterminate
์ useState
๋ฅผ ์ถ๊ฐํ์ต๋๋ค. ๊ทธ๋ฌ๋ฉด ํจ๊ณผ๋ [indeterminate]
๋ฅผ ์ธ์๋ก ๋ฐ์๋ค์
๋๋ค. ํ์ฌ๋ ๋ณ๊ฒฝํ์ง ์์ง๋ง ๋์ค์ ๋ณ๊ฒฝํ๋ฉด ํจ๊ณผ๊ฐ ์์ ๊ฒ ๊ฐ์ต๋๊น? ๋ฐ๋ผ์ ์ฝ๋๋ ๋ฏธ๋์ ๊ฐ๋ฅํ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ์กฐ๊ธ ๋ ์ ์์ธกํฉ๋๋ค.
๊ทธ๋์ ๋๋ ์ผ๋ถ html์ ์ ๋ฌํ๊ณ ๊ทธ๊ฒ์ dangerouslySetInnerHtml
์ ํจ๊ป ์ฌ์ฉํ์ฌ ๋ด ๊ตฌ์ฑ ์์(์ผ๋ถ ํธ์ง ๋ด์ฉ)๋ฅผ ์
๋ฐ์ดํธํ๋ ๋ค์๊ณผ ๊ฐ์ (๊ฐ์ฅ์๋ฆฌ?) ์ฌ๋ก๋ฅผ ์ป์์ต๋๋ค.
html
์ํ์ ์ฌ์ฉํ์ง ์๊ณ ref.current.querySelectorAll
๋ฅผ ์ฌ์ฉํ์ฌ ๋ง๋ฒ์ ๊ฑธ ์ ์๋ ์ฐธ์กฐ๋ฅผ ์ฌ์ฉํฉ๋๋ค.
์ด์ ๋ช
์์ ์ผ๋ก ์ฌ์ฉํ์ง ์๋๋ผ๋ useEffect
์ข
์์ฑ์ html
๋ฅผ ์ถ๊ฐํด์ผ ํฉ๋๋ค. ์ค์ ๋ก ๊ท์น์ ๋นํ์ฑํํด์ผ ํ๋ ์ฌ์ฉ ์ฌ๋ก์
๋๊น?
์์ด๋์ด๋ ํธ์ง ์ฝํ ์ธ ์์ ๋ชจ๋ ๋งํฌ ํด๋ฆญ์ ๊ฐ๋ก์ฑ๊ณ ์ผ๋ถ ๋ถ์์ ์ถ์ ํ๊ฑฐ๋ ๊ธฐํ ๊ด๋ จ ์์ ์ ์ํํ๋ ๊ฒ์ ๋๋ค.
๋ค์์ ์ค์ ๊ตฌ์ฑ ์์์ ์ถ์๋ ์์
๋๋ค.
https://codesandbox.io/s/8njp0pm8v2
react-redux๋ฅผ ์ฌ์ฉํ๊ณ ์์ผ๋ฏ๋ก mapDispatchToProps
์์ props์ action Creator๋ฅผ ์ ๋ฌํ๊ณ hook์์ ํด๋น action Creator๋ฅผ ์ฌ์ฉํ๋ฉด exhaustive-deps
๊ฒฝ๊ณ ๊ฐ ํ์๋ฉ๋๋ค.
๊ทธ๋์ ๋น์ฐํ ์ข ์์ฑ ๋ฐฐ์ด์ redux ์ก์ ์ ์ถ๊ฐํ ์ ์์ง๋ง, redux ์ก์ ์ ํจ์์ด๊ณ ์ ๋ ๋ฐ๋์ง ์๊ธฐ ๋๋ฌธ์ ๋ถํ์ํ์ง ์์ต๋๊น?
const onSubmit = React.useCallback(
() => {
props.onSubmit(emails);
},
[emails, props]
);
๋ฆฐํธ๊ฐ deps ๋ฅผ [emails, props.onSubmit]
๋ก ์์ ํ๊ธฐ๋ฅผ ๊ธฐ๋ํ์ง๋ง ์ง๊ธ์ ํญ์ deps ๋ฅผ [emails, props]
๋ก ์์ ํฉ๋๋ค.
- ์ฌ์ ํ ์๋๋ฅผ ํํํ๋ ์ต์ํ์ ์ฝ๋ ์์ ๋ฅผ ๋ณด์ฌ์ฃผ๋ CodeSandbox("foo bar"๊ฐ ์๋๋ผ ๊ตฌํํ๋ ์ค์ UI ํจํด ).
https://codesandbox.io/s/xpr69pllmz
- ์ฌ์ฉ์๊ฐ ์ํ ํ๋
์ฌ์ฉ์๊ฐ ์ด๋ฉ์ผ์ ์ถ๊ฐํ๊ณ ํด๋น ์ด๋ฉ์ผ์ ์ฑ์ ์ด๋ํฉ๋๋ค. ๋ด ๋ฌธ์ ์ ๊ด๋ จ์ด ์๊ธฐ ๋๋ฌธ์ ์๋์ ์ผ๋ก ๋๋จธ์ง UI๋ฅผ button
์ ๊ฑฐํ์ต๋๋ค.
- Hook/์ปดํฌ๋ํธ์ ์๋๋ API ์ ๋ํ ์ค๋ช ์ ๋๋ค.
๋ด ๊ตฌ์ฑ ์์์๋ onSubmit: (emails: string[]) => void
๋จ์ผ ์ํ์ด ์์ต๋๋ค. ์ฌ์ฉ์๊ฐ ์์์ ์ ์ถํ ๋ emails
์ํ๋ก ํธ์ถ๋ฉ๋๋ค.
ํธ์ง: https://github.com/facebook/react/issues/14920#issuecomment -467494468์์ ๋ต๋ณํ์ต๋๋ค.
์ด๊ฒ์ ๊ธฐ์ ์ ์ผ๋ก
props.foo()
๊ฐprops
์์ฒด๋ฅผthis
๋กfoo
ํธ์ถ๋ก ์ ๋ฌํ๊ธฐ ๋๋ฌธ์ ๋๋ค. ๋ฐ๋ผ์foo
๋ ์์์ ์ผ๋กprops
์ ์ข ์๋ ์ ์์ต๋๋ค. ํ์ง๋ง ์ด ๊ฒฝ์ฐ์๋ ๋ ๋์ ๋ฉ์์ง๊ฐ ํ์ํฉ๋๋ค. ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ์ ํญ์ ๊ตฌ์กฐ๋ฅผ ๋ถํดํ๋ ๊ฒ์ ๋๋ค.
ํ์ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํตํฉํ ๋ ํ์ฌ ๋ฐ ์ ๋ฐ์ดํธ๊ฐ ๋๋ ทํ๊ฒ ๋ค๋ฅผ ์ ์๋ค๋ ์ ์ ๊ณ ๋ คํ์ง ์์ต๋๋ค. ๋ชจ๋ ๋ ๋์์ ์ธ์คํด์ค๊ฐ ํ๊ดด๋์ด์๋ ์ ๋๋ฏ๋ก ์ ๋ฐ์ดํธ ํจ๊ณผ๋ฅผ ๋ง์ดํธ์ ํฌํจํ ์ ์์ต๋๋ค(๋ฐฐ์ด์ ์์ ํ ์ ๊ฑฐ).
์๋ ํ์ธ์,
์ฌ๊ธฐ ๋ด ์ฝ๋์ ๋ฌด์์ด ๋ฌธ์ ์ธ์ง ํ์คํ์ง ์์ต๋๋ค.
const [client, setClient] = useState(0);
useEffect(() => {
getClient().then(client => setClient(client));
}, ['client']);
React Hook useEffect has a complex expression in the dependency array. Extract it to a separate variable so it can be statically checked
๋ฐ์์ด์
@joelmoss @sylvainbaronnet ๊ทํ์ ์๊ฒฌ์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค. ๊ทธ๋ฌ๋ ๋ฌธ์ ์ ๋งจ ์์ ์์ฒญํ ์ ๋ณด๊ฐ ํฌํจ๋์ด ์์ง ์์๊ธฐ ๋๋ฌธ์ ๊ทํ์ ์๊ฒฌ์ ์จ๊ฒผ์ต๋๋ค. ์ปจํ ์คํธ๊ฐ ์๊ธฐ ๋๋ฌธ์ ๋ชจ๋ ์ฌ๋์ด ์ด ํ ๋ก ์ ๋ถํ์ํ๊ฒ ์ด๋ ต๊ฒ ๋ง๋ญ๋๋ค. ๋ค์ ๊ฒ์ํ๊ณ ๋ชจ๋ ๊ด๋ จ ์ ๋ณด๋ฅผ ํฌํจํ๋ฉด ๋ํ๋ฅผ ๊ณ์ํ๊ฒ ์ต๋๋ค(๋งจ ์ ๊ฒ์๋ฌผ ์ฐธ์กฐ). ์ํด ํด ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค.
์ฝ๋๊ฐ ์๋ ๊ทธ๋๋ก ์ค๋ฅ๊ฐ ๋ฐ์ํด์๋ ์ ๋๋ค๊ณ ์๊ฐํฉ๋๋ค. setLastName
๊ฐ ๋ฐฐ์ด์ ํฌํจ๋์ด์ผ ํ๋ค๊ณ 35ํ์์ ๋ฐ๋ก ์คํ๋ฉ๋๋ค. ๊ทธ๊ฒ์ ๋ํด ๋ฌด์์ ํ ์๊ฐ์ด ์์ต๋๊น? ๋ด๊ฐ ์์์น ๋ชปํ ์ผ์ ํ๊ณ ์๋ ๊ฑธ๊น?
๋๋ ์์ ํ ์ดํดํ๊ณ ์ผ๋ฐ์ ์ผ๋ก ๋น์ ์ ์ํด ๋ชจ๋ ๊ฒ์ ํ ๊ฒ์ด์ง๋ง ๋์ ํน์ ํ ๊ฒฝ์ฐ์๋ ์ด๋ค ์ฝ๋๋ ๋์๊ฒ ๊ณ ์ ํ์ง ์์ต๋๋ค. ํํฌ ์ธ๋ถ์์ ์ ์๋๊ณ ํํฌ ๋ด์์ ์ฌ์ฉ๋๋ ํจ์(์ฆ, redux ์์ ์์ฑ์)๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด ํด๋น ํจ์๋ฅผ ํํฌ dep๋ก ์ถ๊ฐํด์ผ ํ๋์ง ์ฌ๋ถ์ ๋ํ ๋จ์ํ ์ง๋ฌธ์ ๋๋ค.
์ฌ์ ํ ๋ ๋ง์ ์ ๋ณด๊ฐ ํ์ํ๋ค๋ฉด ์ฝ๋์๋๋ฐ์ค๋ฅผ ์์ฑํ๊ฒ ๋์ด ๊ธฐ์ฉ๋๋ค. ๊ณ ๋ง์
@joelmoss ๋ด
์, CodeSandbox๋ ์ฌ์ ํ ๋์์ด ๋ ๊ฒ์ ๋๋ค. ํ๋ฃจ ์ข ์ผ ์ฌ๋๋ค์ ์ฝ๋ ์กฐ๊ฐ ์ฌ์ด๋ฅผ ์ปจํ ์คํธ ์ ํํ๋ ๊ฒ์ด ์ด๋ค ๊ฒ์ธ์ง ์์ํด ๋ณด์ญ์์ค. ์์ฒญ๋ ์ ์ ์ ํผํด์ ๋๋ค. ๊ทธ๋ค ์ค ๋๊ตฌ๋ ๋์ผํ๊ฒ ๋ณด์ด์ง ์์ต๋๋ค. ์ฌ๋๋ค์ด Redux์์ ์ก์ ์์ฑ๊ธฐ๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด๋ React ์ธ๋ถ์ ๋ค๋ฅธ ๊ฐ๋ ์ ๊ธฐ์ตํด์ผ ํ๋ ๊ฒฝ์ฐ์๋ ํจ์ฌ ๋ ์ด๋ ต์ต๋๋ค. ๋ฌธ์ ๋ ๋น์ ์๊ฒ ๋ถ๋ช ํ๊ฒ ๋ค๋ฆด์ง ๋ชจ๋ฅด์ง๋ง ๋น์ ์ด ์๋ฏธํ๋ ๋ฐ๊ฐ ๋์๊ฒ๋ ์ ํ ๋ถ๋ช ํ์ง ์์ต๋๋ค.
@gaearon ๋๋ ๊ทธ๊ฒ์ด ์๋ฏธ๊ฐ ์๋ค๋ ๊ฒ์ ์ดํดํฉ๋๋ค. ์ค์ ๋ก ๋ด๊ฐ ๋ฌ์ฑํ๊ณ ์ถ์๋ ์ด์ ๋ ๋ค์๊ณผ
ํจ๊ณผ๋ฅผ ์คํํ๊ณ ํ ๋ฒ๋ง(๋ง์ดํธ ๋ฐ ๋ง์ดํธ ํด์ ์) ์ ๋ฆฌํ๋ ค๋ ๊ฒฝ์ฐ ๋ ๋ฒ์งธ ์ธ์๋ก ๋น ๋ฐฐ์ด([])์ ์ ๋ฌํ ์ ์์ต๋๋ค.
๋ง์ ์ค๋ช ๊ฐ์ฌํฉ๋๋ค. (๊ทธ๋ฆฌ๊ณ ์ฃผ์ ๋ฅผ ๋ฒ์ด๋์ ์ฃ์กํฉ๋๋ค)
๋ค์์ ๋ด๊ฐ ๊ตฌํํ๋ ์ฝ๋ ๋ฒ์ ์ ๋๋ค. ๋ณ๊ฑฐ ์๋ ๊ฒ ๊ฐ์ง๋ง ํจํด์ด ์ค์ ์ฝ๋์ 100% ๋์ผํฉ๋๋ค.
https://codesandbox.io/s/2x4q9rzwmp?fontsize=14
์ด ์์์๋ ๋ชจ๋ ๊ฒ์ด ์ ์๋ํฉ๋๋ค! ๋ฆฐํฐ ๋ฌธ์ ๋ฅผ ์ ์ธํ๊ณ .
ํจ๊ณผ์์ ํจ์๋ฅผ ์คํํ๊ณ ์๋ ์ด์ ๊ฐ์ ํ์ผ์ด ์ฌ๋ฌ ๊ฐ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ํน์ ์กฐ๊ฑด์ด ์ถฉ์กฑ๋ ๋๋ง๋ค ์คํ๋๊ธฐ๋ฅผ ์ํฉ๋๋ค(์: ์๋ฆฌ์ฆ ID ๋ณ๊ฒฝ). ๋ฐฐ์ด์ ํจ์๋ฅผ ํฌํจํ๊ณ ์ถ์ง ์์ต๋๋ค.
์ด๊ฒ์ ์๋๋ฐ์ค ์ฝ๋์์ ์คํํ ๋ ๋ฆฐํฐ์์ ์ป์ ๊ฒ์ ๋๋ค.
25:5 warning React Hook useEffect has a missing dependency: 'fetchPodcastsFn'. Either include it or remove the dependency array react-hooks/exhaustive-deps
๋ด ์ง๋ฌธ์ ์ด๊ฒ์ด ์ด๋ป๊ฒ ์๋ํด์ผ ํฉ๋๊น(linter ๊ท์น ๋๋ ํํฌ ๋ฐฐ์ด ๊ท์น)? ์ด ํจ๊ณผ๋ฅผ ๋ ๊ด์ฉ์ ์ผ๋ก ์ค๋ช ํ๋ ๋ฐฉ๋ฒ์ด ์์ต๋๊น?
@svenanders , fetchPodcastsFn
๋ฅผ ํฌํจํ๊ณ ์ถ์ง ์์ ์ด์ ๊ฐ ๊ถ๊ธํฉ๋๋ค. ๋ ๋๋งํ ๋๋ง๋ค ๋ณ๊ฒฝ๋๊ธฐ ๋๋ฌธ์
๋๊น? ๊ทธ๋ ๋ค๋ฉด ํด๋น ํจ์๋ฅผ ๋ฉ๋ชจํํ๊ฑฐ๋ ์ ์ ์ผ๋ก ๋ง๋ค๊ณ ์ถ์ ๊ฒ์
๋๋ค(๋งค๊ฐ๋ณ์๊ฐ ์๋ ๊ฒฝ์ฐ).
ํ๋๋ ๋ช
ํ์ฑ์ ๊ดํ ๊ฒ์
๋๋ค. ํจ์๋ฅผ ๋ณผ ๋ ์ธ์ ์คํ๋์ด์ผ ํ๋์ง ์ฝ๊ฒ ์ดํดํ๊ณ ์ถ์ต๋๋ค. ์ด๋ ์ด์ _one_ id๊ฐ ํ์๋๋ฉด ๋งค์ฐ ๋ช
ํํฉ๋๋ค. ๊ทธ id์ ๊ธฐ๋ฅ์ ๋ณด๋ฉด ๋ ํผ๋์ค๋ฌ์์ง๋๋ค. ๋ฌด์จ ์ผ์ด ์ผ์ด๋๊ณ ์๋์ง ์ดํดํ๋ ค๋ฉด ์๊ฐ๊ณผ ๋
ธ๋ ฅ์ ๋ค์ฌ์ผ ํ๊ณ , ์ฌ์ง์ด ๊ธฐ๋ฅ์ ๋๋ฒ๊น
ํ ์๋ ์์ต๋๋ค.
๋ด ๊ธฐ๋ฅ์ ๋ฐํ์์ ๋ณ๊ฒฝ๋์ง ์์ผ๋ฏ๋ก ๋ฉ๋ชจ ์์ฑ์ด ์ค์ํ์ง ๋ชจ๋ฅด๊ฒ ์ต๋๋ค.
https://codesandbox.io/s/4xym4yn9kx
์ฌ์ฉ์๋ ํ์ด์ง์ ๊ฒฝ๋ก์ ์ก์ธ์คํ์ง๋ง ์ํผ ์ฌ์ฉ์๊ฐ ์๋๋ฏ๋ก ํ์ด์ง์์ ๋ค๋ฅธ ๊ณณ์ผ๋ก ๋ฆฌ๋๋ ์
ํ๋ ค๊ณ ํฉ๋๋ค. props.navigate
๋ ๋ผ์ฐํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํตํด ์ฃผ์
๋๋ฏ๋ก ์ค์ ๋ก ํ์ด์ง ๋ค์ ๋ก๋๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด window.location.assign
๋ฅผ ์ฌ์ฉํ๊ณ ์ถ์ง ์์ต๋๋ค.
๋ชจ๋ ๊ฒ์ด ์๋ํฉ๋๋ค!
๋๋ ์ฝ๋ ์๋ ๋ฐ์ค๋ก ์ ๋๋ก ์์กด์ฑ์ ๋ฃ์ดํ์ง๋ง ๋ฆฐํฐ ์ข
์์ฑ ๋ชฉ๋ก์ด ์์ด์ผํ๋ค๊ณ ๋์๊ฒ ๋งํ๊ณ props
๋์ props.navigate
. ์ ๊ทธ๋ฐ ๊ฒ๋๊น?
์คํฌ๋ฆฐ์ท์ด ์๋ ํธ์! https://twitter.com/ferdaber/status/1098966716187582464
ํธ์ง: ์ด๊ฒ์ด ๋ฒ๊ทธ๊ฐ ๋ ์ ์๋ ํ ๊ฐ์ง ์ ํจํ ์ด์ ๋ navigate()
๊ฐ ๋ฐ์ธ๋ฉ๋ this
์ ์์กดํ๋ ๋ฉ์๋์ธ ๊ฒฝ์ฐ์
๋๋ค. ์ด ๊ฒฝ์ฐ ๊ธฐ์ ์ ์ผ๋ก props
๋ด๋ถ์ ๋ด์ฉ์ด ๋ณ๊ฒฝ๋๋ฉด ๋ด๋ถ์ ๋ด์ฉ์ด ๋ณ๊ฒฝ๋ฉ๋๋ค this
๋ ๋ณ๊ฒฝ๋ฉ๋๋ค.
์ฝ๋์๋๋ฐ์ค: https://codesandbox.io/s/711r1zmq50
์๋ํ API:
์ด ํํฌ๋ฅผ ์ฌ์ฉํ๋ฉด ๋น ๋ฅด๊ฒ ๋ณํํ๋ ๊ฐ์ ๋๋ฐ์ด์คํ ์ ์์ต๋๋ค. debounced ๊ฐ์ useDbounce ํํฌ๊ฐ ์ง์ ๋ ์๊ฐ ๋์ ํธ์ถ๋์ง ์์ ๊ฒฝ์ฐ์๋ง ์ต์ ๊ฐ์ ๋ฐ์ํฉ๋๋ค. ๋ ์ํผ์์์ ๊ฐ์ด useEffect์ ํจ๊ป ์ฌ์ฉํ๋ฉด API ํธ์ถ๊ณผ ๊ฐ์ ๋น์ฉ์ด ๋ง์ด ๋๋ ์์ ์ด ๋๋ฌด ์์ฃผ ์คํ๋์ง ์๋๋ก ์ฝ๊ฒ ํ์ธํ ์ ์์ต๋๋ค.
๋จ๊ณ:
์ด ์์์๋ Marvel Comic API๋ฅผ ๊ฒ์ํ๊ณ useDebounce๋ฅผ ์ฌ์ฉํ์ฌ ๋ชจ๋ ํค ์ ๋ ฅ์์ API ํธ์ถ์ด ์คํ๋๋ ๊ฒ์ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด useDebounce Hook ์ ๊ณ ๋ คํ์ญ์์ค. ์ค์ ์ฌ์ฉ์์(์ ์ด๋ ์ฐ๋ฆฌ์ ๊ฒฝ์ฐ) delay
๋ ์ฒซ ๋ฒ์งธ ๋ ๋๋ง ํ ๋ณ๊ฒฝ๋์ง ์์ง๋ง ๋ชจ๋ ์ฌ๋ ๋๋ง์์ ๋ณ๊ฒฝ๋์๋์ง ์ฌ๋ถ๋ฅผ ํ์ธํ๊ณ ์์ต๋๋ค. ๊ทธ๋์,์ด ํํฌ์ ๋ ๋ฒ์งธ ์ธ์ useEffect
์
๋๋ค ๋ ๋์๊ฐ๋๊ฒํฉ๋๋ค [value]
๋์ [value, delay]
.
์์ ํ๋ฑ ๊ฒ์ฌ๊ฐ ๋งค์ฐ ์ ๋ ดํ๋ค๊ณ ์๊ฐํ์ง ๋ง์ญ์์ค. ์ ๋ต์ ์ผ๋ก ๋ฐฐ์นํ๋ฉด ์ฑ์ ๋์์ด ๋ ์ ์์ง๋ง ๋ชจ๋ ๋จ์ผ ๊ตฌ์ฑ ์์๋ฅผ ์์ํ๊ฒ ๋ง๋๋ ๊ฒ์ ์ค์ ๋ก ์ฑ์ ๋๋ฆฌ๊ฒ ๋ง๋ค ์ ์์ต๋๋ค. ์ ์ถฉ์.
์ข ์์ฑ ๋ฐฐ์ด์ ๋ชจ๋ ๊ฒ์ ์ถ๊ฐํ๋ฉด ๋ชจ๋ ๊ณณ์์ ์์ ๊ตฌ์ฑ ์์๋ฅผ ์ฌ์ฉํ๋ ๊ฒ๊ณผ ๋์ผํ(๋๋ ๋ ๋์) ์ฑ๋ฅ ๋ฌธ์ ๊ฐ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ฐ๋ฆฌ๊ฐ ์ฌ์ฉํ๋ ๊ฐ โโ์ค ์ผ๋ถ๊ฐ ๋ณ๊ฒฝ๋์ง ์๋๋ค๋ ๊ฒ์ ์๊ณ ์๋ ๋ง์ ์๋๋ฆฌ์ค๊ฐ ์์ผ๋ฏ๋ก @gaearon์ด ๋งํ๋ฏ์ด ์์ ํ๋ฑ ๊ฒ์ฌ๊ฐ ๋งค์ฐ ์ ๋ ดํ์ง ์๊ณ ์ฑ์ ๋๋ฆฌ๊ฒ ๋ง๋ญ๋๋ค.
๊ท์น์ ๋ฐ๋ผ ์ฌ์ฉ์ ์ง์ ํํฌ์์ ์๋์ผ๋ก ์๋ํ๋๋ก ์ด ๊ท์น์ ํ์ฑํํ๋ ๊ฒ์ ๋ํ ๋ช ๊ฐ์ง ํผ๋๋ฐฑ์ด ์์ต๋๋ค.
์์ค ์ฝ๋์์ ์ฌ๋๋ค์ด ์ ๊ท์์ ์ง์ ํ์ฌ ์ฌ์ฉ์ ์ ์ ํํฌ๋ฅผ ์ด๋ฆ์ผ๋ก ์บก์ฒํ ์ ์๋๋ก ํ๋ ค๋ ์๋๊ฐ ์์์ ์ ์ ์์ต๋๋ค.
React ํ์ ์์กด์ฑ ๋ฐฐ์ด์ด ์๋ ์ฌ์ฉ์ ์ ์ ํํฌ์ ๋ํ ์ถ๊ฐ ๋ช
๋ช
๊ท์น์ ๋ํด ์ด๋ป๊ฒ ์๊ฐํ ๊น์? ํํฌ๋ ์ด๋ฏธ ์ด ํ๋ฌ๊ทธ์ธ์์ ํํฌ๋ก ๊ฐ์งํ๊ธฐ ์ํด use
์ ๋์ฌ๊ฐ ๋ถ๋ ๊ท์น์ ๋ฐ๋ฆ
๋๋ค. ํน์ ์ข
์์ฑ์ ์์กดํ๋ ์ฌ์ฉ์ ์ง์ ํํฌ๋ฅผ ๊ฐ์งํ๊ธฐ ์ํด ์ ์ํ๋ ๊ท์น์ WithDeps
์ ๊ฐ์ ์ผ์ข
์ ์ ๋ฏธ์ฌ๊ฐ ๋ ๊ฒ์
๋๋ค. ์ฆ, ์ ์ฒด ์ฌ์ฉ์ ์ง์ ํํฌ ์ด๋ฆ์ useCustomHookWithDeps
์ ๊ฐ์ ์ ์์ต๋๋ค. WithDeps
์ ๋ฏธ์ฌ๋ ํ๋ฌ๊ทธ์ธ์ ์ต์ข
๋ฐฐ์ด ์ธ์๊ฐ ์ข
์์ฑ ์ค ํ๋์์ ์๋ ค์ค๋๋ค.
ํ๋ฌ๊ทธ์ธ์ ์ฌ์ ํ โโregexes๋ฅผ ์ถ๊ฐ๋ก ์ง์ํ ์ ์์ง๋ง ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์๋น์๊ฐ ๋ชจ๋ ์ฌ์ฉ์ ์ ์์ ๋ํด ํ๋ฌ๊ทธ์ธ์ ๋ช
์์ ์ผ๋ก ๊ตฌ์ฑํ๋๋ก ํ๋ ๋์ WithDeps
์ ๋ฏธ์ฌ๊ฐ ๋ถ์ ์ฌ์ฉ์ ์ ์ ํํฌ๋ฅผ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์ฑ์๊ฐ ๊ฐ๋จํ ๋ด๋ณด๋ผ ์ ์๋๋ก ํ๋ฉด ํฐ ์ด์ ์ด ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ 3์ ๋๋ ๋ค๋ฅธ ๋ฐฉ์์ผ๋ก ์ฐ๊ฒฐํฉ๋๋ค.
์ฌ์ฉ์ ์ ์ ๋๋ฑ์ฑ ๊ฒ์ฌ๋ฅผ ๊ฒฝ๊ณ ํ๊ณ ์๋์ผ๋ก ์ ๊ฑฐํฉ๋๋ค.
const myEqualityCheck = a => a.includes('@');
useCallback(
() => {
// ...
},
[myEqualityCheck(a)]
);
useEffect์ ๊ฒฝ์ฐ ํด๋น "์ข ์์ฑ"์ด ํจ๊ณผ๊ฐ ๋ฐ์ํ๋ ๋ฐฉ์์ ๋ณ๊ฒฝํ๊ธฐ ๋๋ฌธ์ "๋ถํ์ํ ์ข ์์ฑ" ๊ฒฝ๊ณ ๊ฐ ๋ํ๋์ผ ํ๋ค๊ณ ์๊ฐํ์ง ์์ต๋๋ค.
๋ถ๋ชจ์ ์์์ด๋ผ๋ ๋ ๊ฐ์ ์นด์ดํฐ๊ฐ ์๋ค๊ณ ๊ฐ์ ํด ๋ณด๊ฒ ์ต๋๋ค.
๊ตฌํ:
const [parent, setParent] = useState(0);
const [child, setChild] = useState(0);
useEffect(
() => {
setChild(0);
},
[parent] // "unnecessary dependency: 'parent'"
);
์ฒ ์ ํ deps ๊ท์น์ React Hook useEffect has an unnecessary dependency: 'parent'. Either exclude it or remove the dependency array.
๊ฒฝ๊ณ ๋ฅผ ์ ๊ณตํฉ๋๋ค.
์ฑ์ด ์๋ํ๋ ๋ฐฉ์์ ๋ณ๊ฒฝํ๊ธฐ ๋๋ฌธ์ ๋ฆฐํฐ๊ฐ ์ด ์ ์์ ํด์๋ ์ ๋๋ค๊ณ ์๊ฐํฉ๋๋ค.
parent
๋ณ๊ฒฝ๋๋ฉด child
๊ฐ 0์ผ๋ก ์ฌ์ค์ ๋ฉ๋๋ค.parent
๊ฐ useEffect
์ ๋์์ ๋ณ๊ฒฝํ๊ณ ์ ๊ฑฐํ๋๋ก ์กฐ์ธํ์ง ์์์ผ ํจ์ ์ธ์ํด์ผ ํฉ๋๋ค.[ํธ์งํ๋ค]
ํด๊ฒฐ ๋ฐฉ๋ฒ์ผ๋ก ๋ค์๊ณผ ๊ฐ์ด ์์ฑํ ์ ์์ต๋๋ค.
const [parent, setParent] = useState(0)
const [child, setChild] = useState(0)
const previousParent = useRef(parent)
useEffect(() => {
if (parent !== previousParent.current) {
setChild(0)
}
previousParent.current = parent
}, [parent])
ํ์ง๋ง ๋ด๊ฐ ์ข์ํ๋ ์๋ณธ ์ค๋ํซ์ "์"๊ฐ ์์ต๋๋ค.
๋ฌธ์ ๋ ์ข ์์ฑ ๋ฐฐ์ด์ ์ฑ๋ฅ ์ต์ ํ์ ์ค์ ๊ตฌ์ฑ ์์ ๋์์ ์ํ ๋ฉ์ปค๋์ฆ์ผ๋ก ํด์ํด์ผ ํ๋์ง ์ฌ๋ถ์ ๋ฌ๋ ค ์๋ค๊ณ ์๊ฐํฉ๋๋ค. React Hooks FAQ๋ ์ฑ๋ฅ์ ์ฌ์ฉํ๋ ์ด์ ์ ๋ํ ์๋ก ์ฑ๋ฅ์ ์ฌ์ฉํ์ง๋ง ์ฑ๋ฅ์ ํฅ์์ํค๊ธฐ ์ํด์๋ง ์ข ์์ฑ ๋ฐฐ์ด์ ์ฌ์ฉํด์ผ ํ๋ค๋ ์๋ฏธ๋ก ์์ ๋ฅผ ํด์ํ์ง ์๊ณ ๋์ ํจ๊ณผ ํธ์ถ์ ๊ฑด๋๋ธ ์ ์๋ ํธ๋ฆฌํ ๋ฐฉ๋ฒ์ผ๋ก ๋ณด์์ต๋๋ค. ์ผ๋ฐ์ ์ผ๋ก.
์ค์ ๋ก ๋ด๋ถ ์บ์๋ฅผ ๋ฌดํจํํ๊ธฐ ์ํด ๋ช ๋ฒ ์ฌ์ฉํ ํจํด์ ๋๋ค.
useEffect(() => {
if (props.invalidateCache) {
cache.clear()
}
}, [props.invalidateCache])
์ด๋ฐ ์์ผ๋ก ์ฌ์ฉํ์ง ์์์ผ ํ๋ ๊ฒฝ์ฐ ์ด ์๊ฒฌ์ ๋ฌด์ํ๊ณ ์๋ ค์ฃผ์ญ์์ค.
@๋ฏธ์คํฐ๋ฆฌ๋ณด
์ด๊ฑด ์ด๋ค๊ฐ์
const [parent, setParent] = useState(0);
const [child, setChild] = useState(0);
const updateChild = React.useCallback(() => setChild(0), [parent]);
useEffect(
() => {
updateChild();
},
[updateChild]
);
๋๋ ๋น์ ์ ๊ทธ ์กฐ๊ฐ์ ์ดํดํ์ง ๋ชปํ ๊ฒ์ ๋๋ค. ์ข ์์ฑ์ ์ฝ๋๋ฅผ ๊ธฐ๋ฐ์ผ๋ก๋ง ๊ฐ์ ํ ์ ์์ง๋ง ๋ฒ๊ทธ์ผ ์ ์์ต๋๋ค. ๋ด ์ ์์ด ๋ฐ๋์ ํด๊ฒฐ๋์ง๋ ์์ง๋ง ์ ์ด๋ ๋ ๋ช ํํ๊ฒ ๋ง๋ญ๋๋ค.
์ด๊ฒ์ ์ด์ ์ getDerivedStateFromProps
๋ฅผ ํตํด ํด๊ฒฐ๋ ๊ฒ ๊ฐ์ต๋๊น? getDerivedStateFromProps๋ฅผ ์ด๋ป๊ฒ ๊ตฌํํฉ๋๊น? ๋๋ค?
@nghiepit ์ฒซ ๋ฒ์งธ ๊ฒ์๋ฌผ(์: CodeSandbox)์์ ํ์ ์ฒดํฌ๋ฆฌ์คํธ๋ฅผ ๋ฌด์ํ๊ธฐ ๋๋ฌธ์ ๋๊ธ์ ์จ๊ฒผ์ต๋๋ค. ์ฒดํฌ๋ฆฌ์คํธ์ ๋ฐ๋ผ ๋ค์ ๊ฒ์ํด ์ฃผ์ธ์. ๊ฐ์ฌ ํด์.
@eps1lon useCallback
์ ๋ํด ์ ํํ ๋์ผํ ๊ฒฝ๊ณ ๊ฐ ํ์๋ ๊ฒ์ด๋ฉฐ ์ผ๋ฐ์ ์ผ๋ก ํด๋น ํจํด์ด ์๋ณธ๋ณด๋ค ๊ฐ์ ๋๋ค๋ ๋ฐ ๋์ํ์ง ์์ง๋ง ์ด์ ๋ํด ์ด์ผ๊ธฐํ๊ธฐ ์ํด ์ฃผ์ ๋ฅผ ํ์ ์ํค๊ณ ์ถ์ง ์์ต๋๋ค. ๋ช
ํํ ํ์๋ฉด, ๋ถํ์ํ ์ข
์์ฑ ๊ท์น์ useEffect
๋๋ useLayoutEffect
๋ํด ์ํ๋์ด์ผ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ์๋ํ๋ฉด ๊ทธ๋ค์ ํจ๊ณผ์ ์ธ ๋
ผ๋ฆฌ๋ฅผ ํฌํจํ ์ ์์ง๋ง useCallback
๋ํ ๊ท์น์ ๊ทธ๋๋ก ์ ์ง๋์ด์ผ ํ๊ธฐ ๋๋ฌธ์
๋๋ค. useMemo
๋ฑ
@MrLeebo ๊ฐ ์ฌ๊ธฐ์์ ์ค๋ช
ํ ๊ฒ๊ณผ ๋์ผํ ๋ฌธ์ /์ ์ ์ ๋ชจ๋ธ ์ง๋ฌธ์ด ์์ต๋๋ค. ๋ด ์ง๊ฐ์ useEffect
์ข
์์ฑ ๊ท์น์ด ๊ทธ๋ ๊ฒ ์๊ฒฉํ ์ ์๋ค๋ ๊ฒ์
๋๋ค. ๊ธฐ๋ณธ ๊ฐ๋
์ฆ๋ช
์์ด๋์ด๋ฅผ ์ํด ์์
ํ๊ณ ์๋ ๋ฏฟ์ ์ ์์ ์ ๋๋ก ์ธ์์ ์ธ ์๊ฐ ์์ต๋๋ค. ๋๋ ์ด ์ฝ๋๊ฐ ํํธ์๊ณ ์์ด๋์ด๊ฐ ํนํ ์ ์ฉํ์ง ์๋ค๋ ๊ฒ์ ์๊ณ ์์ง๋ง, ๋น๋ฉดํ ๋ฌธ์ ์ ๋ํ ์ข์ ์๋ผ๊ณ ์๊ฐํฉ๋๋ค. @MrLeebo๊ฐ ๋ด๊ฐ ๊ฝค ์ ๊ฐ์ง๊ณ ์๋ ์ง๋ฌธ์ ํํํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
๋ฌธ์ ๋ ์ข ์์ฑ ๋ฐฐ์ด์ ์ฑ๋ฅ ์ต์ ํ์ ์ค์ ๊ตฌ์ฑ ์์ ๋์์ ์ํ ๋ฉ์ปค๋์ฆ์ผ๋ก ํด์ํด์ผ ํ๋์ง ์ฌ๋ถ์ ๋ฌ๋ ค ์๋ค๊ณ ์๊ฐํฉ๋๋ค. React Hooks FAQ๋ ์ฑ๋ฅ์ ์ฌ์ฉํ๋ ์ด์ ์ ๋ํ ์๋ก ์ฑ๋ฅ์ ์ฌ์ฉํ์ง๋ง ์ฑ๋ฅ์ ํฅ์์ํค๊ธฐ ์ํด์๋ง ์ข ์์ฑ ๋ฐฐ์ด์ ์ฌ์ฉํด์ผ ํ๋ค๋ ์๋ฏธ๋ก ์์ ๋ฅผ ํด์ํ์ง ์๊ณ ๋์ ํจ๊ณผ ํธ์ถ์ ๊ฑด๋๋ธ ์ ์๋ ํธ๋ฆฌํ ๋ฐฉ๋ฒ์ผ๋ก ๋ณด์์ต๋๋ค. ์ผ๋ฐ์ ์ผ๋ก.
https://codesandbox.io/s/5v9w81j244
ํนํ useDelayedItems
์ useEffect
ํํฌ๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค. ํ์ฌ items
์์ฑ์ ์ข
์์ฑ ๋ฐฐ์ด์ ํฌํจํ๋ฉด linting ์ค๋ฅ๊ฐ ๋ฐ์ํ์ง๋ง ํด๋น ์์ฑ์ด๋ ๋ฐฐ์ด์ ์์ ํ ์ ๊ฑฐํ๋ฉด ์ํ์ง ์๋ ๋์์ด ๋ฐ์ํฉ๋๋ค.
useDelayedItems
ํํฌ์ ๊ธฐ๋ณธ ์์ด๋์ด๋ ํญ๋ชฉ ๋ฐฐ์ด๊ณผ ๊ตฌ์ฑ ๊ฐ์ฒด(ms ๋จ์ ์ง์ฐ, ์ด๊ธฐ ํ์ด์ง ํฌ๊ธฐ)๊ฐ ์ฃผ์ด์ง๋ฉฐ, ์ฒ์์๋ ๊ตฌ์ฑ๋ ํ์ด์ง ํฌ๊ธฐ์ ๋ฐ๋ผ ํญ๋ชฉ์ ํ์ ์งํฉ์ ๋ฐ๊ฒ ๋ฉ๋๋ค. config.delay
๊ฐ ์ง๋๋ฉด ํญ๋ชฉ์ ์ด์ ์ ์ฒด ํญ๋ชฉ ์ธํธ๊ฐ ๋ฉ๋๋ค. ์๋ก์ด ํญ๋ชฉ ์ธํธ๊ฐ ์ ๋ฌ๋๋ฉด ํํฌ๋ ์ด "์ง์ฐ" ๋
ผ๋ฆฌ๋ฅผ ๋ค์ ์คํํด์ผ ํฉ๋๋ค. ์์ด๋์ด๋ ํฐ ๋ชฉ๋ก์ ์ง์ฐ๋ ๋ ๋๋ง์ ๋งค์ฐ ์กฐ์กํ๊ณ ๋ฉ์ฒญํ ๋ฒ์ ์
๋๋ค.
์ด ๊ท์น์ ๋ํ ๋ชจ๋ ์์ ์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค. ๊ฐ๋ฐํ ๋ ๋งค์ฐ ๋์์ด ๋์์ต๋๋ค. ๋ด ์์ ์ ํ์ง์ด ์์ฌ์ค๋ฝ๋๋ผ๋ ์ด๋ฌํ ์ฐ์ฐ์๊ฐ ์ด๋ป๊ฒ ๋จ์ฉ/์ฌ์ฉ๋ ์ ์๋์ง์ ๋ํ ํต์ฐฐ๋ ฅ์ ์ ๊ณตํ๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
ํธ์ง : ๋๋ ํ๋ ์๋์ ๊ด๋ จ๋ ์ฝ๋ ๋ฐ ์์ ๋ด๋ถ์ ๋ช ๊ฐ์ง ๋ช ํํ ์ค๋ช ์ ์ถ๊ฐํ์ต๋๋ค. ์ ๋ณด๊ฐ ์ถฉ๋ถํ๊ธฐ๋ฅผ ๋ฐ๋๋๋ค. ํ์ง๋ง ์ฌ์ ํ ํผ๋์ค๋ฌ์ด ์ ์ด ์์ผ๋ฉด ์๋ ค์ฃผ์ญ์์ค.
๋ค๋ฅธ ๊ฐ์ ๊ฒฐํฉํ ๋จ์ผ ๊ฐ์ ์ด๋ป์ต๋๊น?
์: fullName์ firstName
๋ฐ lastName
์์ ํ์๋ฉ๋๋ค. fullName
๋ณ๊ฒฝ๋ ๋๋ง ํจ๊ณผ๋ฅผ ํธ๋ฆฌ๊ฑฐํ๊ณ (์: ์ฌ์ฉ์๊ฐ "์ ์ฅ"์ ๋๋ ์ ๋) ํจ๊ณผ์์ ๊ตฌ์ฑํ๋ ๊ฐ์๋ ์ก์ธ์คํ๋ ค๊ณ ํฉ๋๋ค.
fullName
๊ฐ ๋ณ๊ฒฝ๋ ํ์ firstName
๋๋ lastName
๋ฅผ ์ถ๊ฐํ๋ฉด ๋ฌธ์ ๊ฐ ํด๊ฒฐ๋ฉ๋๋ค.
@aweary useEffect
์ํ ๋ณ๊ฒฝ ๊ฐ์ ์ฐธ์กฐ์์ ์ด๋ค ๊ฐ์น๋ฅผ ์ป๊ณ ์๋์ง ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. onClick
์ด "ํจ๊ณผ"๋ฅผ ์ฒ๋ฆฌํด์ผ ํ๋ ๊ฒ ๊ฐ์ต๋๋ค.
https://codesandbox.io/s/0m4p3klpyw
๋ค๋ฅธ ๊ฐ์ ๊ฒฐํฉํ๋ ๋จ์ผ ๊ฐ์ ๊ดํด์๋ useMemo
๊ฐ ์๋ง๋ ์ํ๋ ๋๋ก ๋ ๊ฒ์
๋๋ค. ์์์ ๊ณ์ฐ์ ์ง์ฐ๋ ํน์ฑ์ ์ฐ๊ฒฐ๋ ๋์๊ณผ ์ ํํ 1:1๋ก ๋งคํ๋์ง ์๋๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
์ด ์์ ์ ๋ํ ์ฝ๋ ๋ฐ ์์ ๋งํฌ๋ฅผ ๋ง๋ค๊ณ ์ด ๊ฒ์๋ฌผ์ ํธ์งํฉ๋๋ค.
๋งค์ฐ ๊ฐ๋จํ ๊ท์น์ด ์์ต๋๋ค. ํ์ฌ ํญ์ด ๋ณ๊ฒฝ๋ ๊ฒฝ์ฐ ๋งจ ์๋ก ์คํฌ๋กคํฉ๋๋ค.
https://codesandbox.io/s/m4nzvryrxj
useEffect(() => {
window.scrollTo(0, 0);
}, [activeTab]);
๊ทธ๋ฆฌ๊ณ React Hook useEffect has an unnecessary dependency: 'activeTab'. Either exclude it or remove the dependency array
๋ฐ์์ต๋๋ค.
๋ํ ์ผ๋ถ ๊ตฌ์ฑ ์์๋ฅผ ๋ง์ด๊ทธ๋ ์ด์ ํ ๋ componentDidMount ๋์์ ๋ณต์ ํ๊ณ ์ถ์ต๋๋ค.
useEffect(() => {
...
}, []);
์ด ๊ท์น์ ์ด๊ฒ์ ๋ํด ์ด์ฌํ ๋ถํํ๊ณ ์์ต๋๋ค. useEffect ๋ฐฐ์ด์ ๋ชจ๋ ์ข ์์ฑ์ ์ถ๊ฐํ๋ ๊ฒ์ ์ฃผ์ ํฉ๋๋ค.
๋ง์ง๋ง์ผ๋ก useEffect ์ ์ ์ ์ธ๋ผ์ธ ํจ์๋ฅผ ์ ์ธํ๋ฉด ๋ค์๊ณผ ๊ฐ์ด ๋ฉ๋๋ค.
https://codesandbox.io/s/nr7wz8qp7l
const foo = () => {...};
useEffect(() => {
foo();
}, []);
๋น์ ์ ์ป์: React Hook useEffect has a missing dependency: 'foo'. Either include it or remove the dependency array
์ข
์์ฑ ๋ชฉ๋ก์ foo๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์ ๋ํด ์ด๋ป๊ฒ ๋๋ผ๋์ง ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ๊ฐ ๋ ๋์์ foo๋ ์๋ก์ด ํจ์์ด๊ณ useEffect๋ ํญ์ ์คํ๋ฉ๋๊น?
@ksaldana1 ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ด๋ถ์ ๋ถ์์ฉ์ ๋ฃ๋ ๊ฒ๋ง์ผ๋ก๋ ์ถฉ๋ถํ์ง ์์ต๋๋ค. ๊ทธ๋ฌ๋ฉด ์ค์ ์ ๋ฐ์ดํธ๊ฐ ์ปค๋ฐ๋๊ธฐ ์ ์ ๋ถ์์ฉ์ด ๋ฐ์ํ์ฌ ์ํ๋ ๊ฒ๋ณด๋ค ๋ ์์ฃผ ๋ถ์์ฉ์ด ํธ๋ฆฌ๊ฑฐ๋ ์ ์์ต๋๋ค.
์
๋ฐ์ดํธ๋ ์ํ๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ด์์ ์ฌ์ฉํ ์ ์๊ธฐ ๋๋ฌธ์ useReducer
์ฌ์ฉํ ๋๋ ์๋ํ์ง ์์ต๋๋ค.
๋ค๋ฅธ ๊ฐ์ ๊ฒฐํฉํ๋ ๋จ์ผ ๊ฐ์ ๊ดํด์๋
useMemo
๊ฐ ์๋ง๋ ์ํ๋ ๊ฐ์ผ ๊ฒ์ ๋๋ค.
์ด ์์์ useMemo
ํ๋ฉด firstName
๋๋ lastName
๋ณ๊ฒฝ๋ ๋๋ง๋ค useMemo
๊ฐ ์ fullName
ํ์ํ๋ฏ๋ก ์ค๋จ๋ฉ๋๋ค. ์ฌ๊ธฐ์ ๋์์ ์ ์ฅ ๋ฒํผ์ ํด๋ฆญํ ๋๊น์ง fullName
๊ฐ ์
๋ฐ์ดํธ๋์ง ์๋๋ค๋ ๊ฒ์
๋๋ค.
@weary ์ด๋ฐ ์์ผ๋ก ์๋ํ ๊น์? https://codesandbox.io/s/lxjm02j50m
๊ถ์ฅ ๊ตฌํ์ด ๋ฌด์์ธ์ง ๋งค์ฐ ๊ถ๊ธํฉ๋๋ค.
๋ํ ๋ง์ํ์ ๋ช ๊ฐ์ง ์ฌํญ์ ๋ํด ๋ ๋ฃ๊ณ ์ถ์ต๋๋ค. ์ด๊ฒ์ ๋ํด ๋ ๋ง์ ์ ๋ณด๋ฅผ ์๋ ค์ค ์ ์์ต๋๊น?
ํธ๋ค๋ฌ์ ํธ๋ฆฌ๊ฑฐ๋ง ๋ฐ ํจ๊ณผ:
์ค์ ์ ๋ฐ์ดํธ๊ฐ ์ปค๋ฐ๋๊ธฐ ์ ์ ๋ถ์์ฉ์ด ๋ฐ์ํ์ฌ ์ํ๋ ๊ฒ๋ณด๋ค ๋ ์์ฃผ ๋ถ์์ฉ์ด ํธ๋ฆฌ๊ฑฐ๋ ์ ์์ต๋๋ค.
์ด๋ฒคํธ ํธ๋ค๋ฌ์์ useReducer
์ํ ์ฌ์ฉ:
์ ๋ฐ์ดํธ๋ ์ํ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๊ฐ์ฌ ํด์!
@bugzpodder ์ข
๋ฅ ๋ฌด๊ด์ํ์ง๋ง ์คํฌ๋กค ํธ์ถ์ ๋ด๋ถ์ ์์ด์ผํ๋ค useLayoutEffect
๋์ useEffect
. ํ์ฌ ์ ๊ฒฝ๋ก๋ก ์ด๋ํ ๋ ๋์ ๋๋ ๊น๋ฐ์์ด ์์ต๋๋ค.
์ด๊ฒ์ด ์๋์ ์ธ ๊ฒ์ธ์ง ์๋์ง ํ์คํ์ง ์์ต๋๋ค:
props์์ ํจ์๋ฅผ ํธ์ถํ ๋ linter๋ ์ ์ฒด props ๊ฐ์ฒด๋ฅผ ์ข ์์ฑ์ผ๋ก ์ถ๊ฐํ ๊ฒ์ ์ ์ํฉ๋๋ค.
์งง์ ๋ฒ์ :
useEffect(function() {
props.setLoading(true)
}, [props.setLoading])
// โ ๏ธ React Hook useEffect has a missing dependency: 'props'.
์ ์ ๋ฒ์ : ์ฝ๋์๋๋ฐ์ค
๋ค์ ์๋ํ์ง๋ง ์ด๋ฒ์๋ ๋ ๊ฐ๋จํฉ๋๋ค ;)
์ํ์์ ํจ์๋ฅผ ์ ๋ฌํ๊ฑฐ๋ ์ค์ ๋ก ์ด๋์์๋ ํํฌ ๋ด๋ถ์์ ํด๋น ํจ์๋ฅผ ์ฌ์ฉํ๋ฉด exhaustive-deps
๊ฒฝ๊ณ ๊ฐ ํ์๋ฉ๋๋ค.
๋ฐ๋ผ์ ์ข ์์ฑ ๋ฐฐ์ด์ ํจ์๋ฅผ ์ถ๊ฐํ ์๋ ์์ง๋ง ํจ์์ด๊ณ ๋ณ๊ฒฝ๋์ง ์๊ธฐ ๋๋ฌธ์ ๋ถํ์ํ์ง ์์ต๋๊น?
-> ์๋๋ฐ์ค
๊ทธ๊ฒ์ด ๋น์ ์ด ํ์๋กํ๋ ๋ชจ๋ ๊ฒ์ด๊ธฐ๋ฅผ ํฌ๋งํ์ง๋ง ๋ด๊ฐ ์๋ฏธํ๋ ๋ฐ๋ฅผ ๋ณด์ฌ์ฃผ๊ธฐ ์ํด ํ์ต๋๋ค .
๊ณ ๋ง์.
๋ฐ๋ผ์ ์ข ์์ฑ ๋ฐฐ์ด์ ํจ์๋ฅผ ์ถ๊ฐํ ์๋ ์์ง๋ง ํจ์์ด๊ณ ๋ณ๊ฒฝ๋์ง ์๊ธฐ ๋๋ฌธ์ ๋ถํ์ํ์ง ์์ต๋๊น?
์ด๊ฒ์ ์ ํํ์ง ์์ต๋๋ค. ํจ์๋ ๋ถ๋ชจ๊ฐ ๋ค์ ๋ ๋๋งํ ๋ ํญ์ ๋ณ๊ฒฝ๋ ์ ์์ต๋๋ค.
@siddharthkp
props์์ ํจ์๋ฅผ ํธ์ถํ ๋ linter๋ ์ ์ฒด props ๊ฐ์ฒด๋ฅผ ์ข ์์ฑ์ผ๋ก ์ถ๊ฐํ ๊ฒ์ ์ ์ํฉ๋๋ค.
์ด๋ ๊ธฐ์ ์ ์ผ๋ก props.foo()
๊ฐ this
๋ฅผ foo
ํธ์ถ๋ก props
์์ฒด๋ฅผ ์ ๋ฌํ๊ธฐ ๋๋ฌธ์
๋๋ค. ๋ฐ๋ผ์ foo
๋ ์์์ ์ผ๋ก props
์ ์์กดํ ์ ์์ต๋๋ค. ํ์ง๋ง ์ด ๊ฒฝ์ฐ์๋ ๋ ๋์ ๋ฉ์์ง๊ฐ ํ์ํฉ๋๋ค. ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ์ ํญ์ ๊ตฌ์กฐ๋ฅผ ๋ถํดํ๋ ๊ฒ์
๋๋ค.
ํจ์๋ ๋ถ๋ชจ๊ฐ ๋ค์ ๋ ๋๋งํ ๋ ํญ์ ๋ณ๊ฒฝ๋ ์ ์์ต๋๋ค.
๋ฌผ๋ก , ํ์ง๋ง ํจ์๊ฐ ์์ ๊ตฌ์ฑ ์์๊ฐ ์๋ ๋ค๋ฅธ ๊ณณ์์ ์ ์๋ ๊ฒฝ์ฐ์๋ ๋ณ๊ฒฝ๋์ง ์์ต๋๋ค.
๋ฌผ๋ก , ํ์ง๋ง ํจ์๊ฐ ์์ ๊ตฌ์ฑ ์์๊ฐ ์๋ ๋ค๋ฅธ ๊ณณ์์ ์ ์๋ ๊ฒฝ์ฐ์๋ ๋ณ๊ฒฝ๋์ง ์์ต๋๋ค.
์ง์ ๊ฐ์ ธ์ค๋ ๊ฒฝ์ฐ ๋ฆฐํธ ๊ท์น์ ํจ๊ณผ deps์ ์ถ๊ฐํ๋๋ก ์์ฒญํ์ง ์์ต๋๋ค. ๋ ๋ ๋ฒ์์ ์๋ ๊ฒฝ์ฐ์๋ง. ๊ทธ๊ฒ์ด ๋ ๋ ๋ฒ์์ ์์ผ๋ฉด ๋ฆฐํธ ๊ท์น์ ๊ทธ๊ฒ์ด ์ด๋์์ ์๋์ง ์์ง ๋ชปํฉ๋๋ค. ์ค๋์ ๋์ ์ด ์๋๋๋ผ๋ ๋๊ตฐ๊ฐ ๋ถ๋ชจ ๊ตฌ์ฑ ์์๋ฅผ ๋ณ๊ฒฝํ๋ฉด ๋ด์ผ์ด ๋ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ ์ง์ ํ๋ ๊ฒ์ด ์ฌ๋ฐ๋ฅธ ๊ธฐ๋ณธ๊ฐ์ ๋๋ค. ์ด์จ๋ ์ ์ ์ด๋ผ๋ฉด ์ง์ ํ๋ ๊ฒ์ด ๋์์ง ์์ต๋๋ค.
thx @gaearon
์ด๋ ๊ธฐ์ ์ ์ผ๋ก
props.foo()
๊ฐthis
๋ฅผfoo
ํธ์ถ๋กprops
์์ฒด๋ฅผ ์ ๋ฌํ๊ธฐ ๋๋ฌธ์ ๋๋ค. ๋ฐ๋ผ์foo
๋ ์์์ ์ผ๋กprops
์ ์์กดํ ์ ์์ต๋๋ค. ํ์ง๋ง ์ด ๊ฒฝ์ฐ์๋ ๋ ๋์ ๋ฉ์์ง๊ฐ ํ์ํฉ๋๋ค. ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ์ ํญ์ ๊ตฌ์กฐ๋ฅผ ๋ถํดํ๋ ๊ฒ์ ๋๋ค.
๊ทธ๊ฒ์ ๋ด ์ง๋ฌธ์๋ ๋๋ตํฉ๋๋ค. ๊ฐ์ฌํฉ๋๋ค! ๐
https://codesandbox.io/s/98z62jkyro
๊ทธ๋์ ๊ฐ ์ ๋ ฅ์ด ์ค์ค๋ก๋ฅผ ๋ฑ๋กํ ์ ์๋๋ก ์ปจํ ์คํธ์ ๋ ธ์ถ๋ API๋ฅผ ์ฌ์ฉํ์ฌ ๋ชจ๋ ์ ๋ ฅ์ ๋ฑ๋กํ์ฌ ์ ๋ ฅ ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ง๋ค๊ณ ์์ต๋๋ค. useRegister๋ผ๋ ์ฌ์ฉ์ ์ ์ ํํฌ๋ฅผ ๋ง๋ค์์ต๋๋ค.
์ :
useEffect(
() => {
register(props.name, props.rules || []);
console.log("register");
return function cleanup() {
console.log("cleanup");
unregister(props.name);
};
},
[props.name, props.rules, register, unregister]
);
props.rules๋ฅผ ์ข ์์ฑ์ ์ผ๋ถ๋ก ๊ฐ์ ํ ๋ ๋ฌดํ ๋ ๋ ๋ฃจํ๋ก ๋๋๋ ๊ฒ ๊ฐ์ต๋๋ค. Props.rules๋ ์ ํจ์ฑ ๊ฒ์ฌ๊ธฐ๋ก ๋ฑ๋กํ ํจ์์ ๋ฐฐ์ด์ ๋๋ค. ์ด๋ ์ด๋ฅผ ์ข ์์ฑ์ผ๋ก ์ ๊ณตํ ๋๋ง ์ด ๋ฌธ์ ๋ฅผ ๊ฐ์งํ์ต๋๋ค. ๋ด ์ฝ๋์๋๋ฐ์ค์์ ์ฝ์์ ์ฌ๋ ๋ฃจํ๋ฅผ ๋ณผ ์ ์์ต๋๋ค.
props.name์ ์ข ์์ฑ์ผ๋ก ์ฌ์ฉํ๋ฉด ์๋ํ ๋๋ก ์๋ํฉ๋๋ค. ๋ค๋ฅธ ์ฌ๋์ด ์ง์ ํ ๋๋ก ์ข ์์ฑ์ ์ ์ฉํ๋ฉด ์์ฉ ํ๋ก๊ทธ๋จ์ ๋์์ด ๋ณ๊ฒฝ๋๋ฉฐ ์ด ๊ฒฝ์ฐ ๋ถ์์ฉ์ด ์ฌ๊ฐํฉ๋๋ค.
@bugzpodder
์ฌ: https://github.com/facebook/react/issues/14920#issuecomment -467212561
useEffect(() => {
window.scrollTo(0, 0);
}, [activeTab]);
์ด๊ฒ์ ์ ๋ฒํ ์ผ์ด์ค์ฒ๋ผ ๋ณด์
๋๋ค. ๋๋ ํจ๊ณผ์ ๋ํด์๋ง ๊ด๋ จ ์๋ deps๋ฅผ ํ์ฉํ๋๋ก ๊ฒฝ๊ณ ๋ฅผ ์ํํ ๊ฒ์
๋๋ค. (ํ์ง๋ง useMemo
๋๋ useCallback
.)
๋ํ ์ผ๋ถ ๊ตฌ์ฑ ์์๋ฅผ ๋ง์ด๊ทธ๋ ์ด์ ํ ๋ componentDidMount ๋์์ ๋ณต์ ํ๊ณ ์ถ์ต๋๋ค.
์ด ๊ท์น์ ์ด๊ฒ์ ๋ํด ์ด์ฌํ ๋ถํํ๊ณ ์์ต๋๋ค. useEffect ๋ฐฐ์ด์ ๋ชจ๋ ์ข ์์ฑ์ ์ถ๊ฐํ๋ ๊ฒ์ ์ฃผ์ ํฉ๋๋ค.
์ฃ์กํฉ๋๋ค. ์ด์ ๋ํ ์๋ฅผ ์ถ๊ฐํ์ง ์์ผ์ ์ ๋ ผ์ํ ๊ธฐํ๋ฅผ ๋์ณค์ต๋๋ค. ์ด๊ฒ์ด ๋ฐ๋ก OP ๊ฒ์๋ฌผ ์ด ๊ตฌ์ฒด์ ์ธ UI ์์ ๋ฅผ
๋ง์ง๋ง์ผ๋ก useEffect ์ ์ ์ ์ธ๋ผ์ธ ํจ์๋ฅผ ์ ์ธํ๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค. https://codesandbox.io/s/nr7wz8qp7l
์ด ๊ฒฝ์ฐ doSomething
๋ฅผ ํจ๊ณผ๋ก ์ฎ๊ธฐ๋ฉด ์ฝ๊ฒ ํด๊ฒฐํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ฉด ์ ์ธํ ํ์๊ฐ ์์ต๋๋ค. ๋๋ useCallback
์ฃผ์์ doSomething
์์ต๋๋ค. ์ ์ธ๋ dep๋ง ์ฌ์ฉํ๋ ํจ์๋ฅผ ์๋ตํ ์ ์๋๋ก ๊ท์น์ ์ํํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๋ค๋ฅธ ํจ์๋ฅผ ํธ์ถํ๋ ํจ์๊ฐ ์๊ณ ์ด๋ฌํ ํจ์ ์ค ํ๋์ prop ๋๋ state๋ฅผ ์ถ๊ฐํ๋ ๊ฒฝ์ฐ ํผ๋๋ ์ ์์ต๋๋ค. ๊ฐ์๊ธฐ ๊ทธ๊ฒ์ ์ ์ด์ ์ผ๋ก ์ฌ์ฉํ๋ ๋ชจ๋ ํจ๊ณผ ๋์ค๋ฅผ ์
๋ฐ์ดํธํด์ผ ํฉ๋๋ค. ํผ๋์ค๋ฌ์ธ ์ ์์ต๋๋ค.
์ด๊ฒ์ด ์ ๊ท์น์ ๋ํ ๊ธฐ๋ฅ ์์ฒญ์ธ์ง ์๋๋ฉด exhaustive-deps
๋ํด ๊ฐ์ ํ ์ ์๋ ์ฌํญ์ธ์ง ๋ชจ๋ฅด๊ฒ ์ต๋๋ค.
import React from 'react'
import emitter from './thing'
export const Foo = () => {
const onChange = () => {
console.log('Thing changed')
}
React.useEffect(() => {
emitter.on('change', onChange)
return () => emitter.off('change', onChange)
}, [onChange])
return <div>Whatever</div>
}
onChange
ํจ์๋ ๋ ๋๋งํ ๋๋ง๋ค ์์ฑ๋๊ธฐ ๋๋ฌธ์ useEffect
hook [onChange]
์ธ์๋ ์ค๋ณต๋๋ฉฐ ์ ๊ฑฐ๋ ์๋ ์์ต๋๋ค.
React.useEffect(() => {
emitter.on('change', onChange)
return () => emitter.off('change', onChange)
- }, [onChange])
+ })
๋ฆฐํฐ๊ฐ ์ด๋ฅผ ๊ฐ์งํ๊ณ ๋ฐฐ์ด ์ธ์๋ฅผ ์ญ์ ํ๋๋ก ์กฐ์ธํ ์ ์์ต๋๋ค.
๋ฐฐ์ด ํญ๋ชฉ ๋ชฉ๋ก์ ์ ์ง ๊ด๋ฆฌํ๊ณ ์์๋๋ฐ ๊ทธ ์ค ํ๋ ์ด์์ด ์์ฑ๋๊ณ ์ด์จ๋ ๋ ๋๋งํ ๋๋ง๋ค ํํฌ๊ฐ ๋ฌดํจํ๋๊ณ ์๋ค๋ ๊ฒ์ ๊นจ๋ซ๋ ์ํฉ์ด ์์์ต๋๋ค.
์ด ๊ท์น์ ๋ํ ๋ช ๊ฐ์ง ์์ ์ฌํญ๊ณผ ๋ ๋์ ๋ฉ์์ง๊ฐ ํฌํจ๋ [email protected]
์ ์ถ์ํ์ต๋๋ค. ํ๊ธฐ์ ์ธ ๊ฒ์ ์๋์ง๋ง ๋ช ๊ฐ์ง ๊ฒฝ์ฐ๋ฅผ ํด๊ฒฐํด์ผ ํฉ๋๋ค. ๋๋จธ์ง๋ ๋ค์์ฃผ์ ๋ด์ผ๊ฒ ๋ค.
๋ํ https://github.com/facebook/react/pull/14996์ "์์ ํ" ๊ธฐ๋ฅ deps๋ฅผ ์๋ตํ ์ ์๋ ์ฒซ ๋ฒ์งธ ๋จ๊ณ๋ฅผ ๊ฒ์ํ์ต๋๋ค
@gaearon ์ข์ ์๊ฐ์ ๋๋ค. ์ด๊ฒ์ ํํฌ๋ฅผ ์ฌ์ฉํ ๋ ๋ ๋์ ์คํ์ผ์ ๊ฐ๋ ๋ฐ ํ์คํ ์ ์ฉํฉ๋๋ค ๐
@gaearon ์ก์ ์ด prop์์ ์ค๋ ๊ฒฝ์ฐ์๋ ์ฌ์ ํ ์๋ํ์ง ์์ต๋๋ค. ๋ค์ ์๋ฅผ ๊ณ ๋ คํ์ญ์์ค.
์ฌ๊ธฐ์ setScrollTop
๋ redux ์์
์
๋๋ค.
Slider
๊ตฌ์ฑ ์์์ ์ด ์์์๋ useEffect
๋ฅผ ์ฌ์ฉํ์ฌ DOM์ ์ฌ์ฉํ ์ ์์ ๋๊น์ง ๋๊ธฐํ์ฌ noUiSlider ๊ตฌ์ฑ ์์๋ฅผ ๋ง์ดํธํ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ ํจ๊ณผ๊ฐ ์คํ๋ ๋ DOM์์ ref๋ฅผ ์ฌ์ฉํ ์ ์๋๋ก [sliderElement]
๋ฅผ ์ ๋ฌํฉ๋๋ค. ์ฐ๋ฆฌ๋ ๊ตฌ์ฑ ์์๋ ์๋ฒ๋ก ๋ ๋๋งํ๋ฏ๋ก ๋ ๋๋ง ์ ์ DOM์ ์ฌ์ฉํ ์ ์๋์ง๋ ํ์ธํฉ๋๋ค. useEffect
์์ ์ฌ์ฉํ๋ ๋ค๋ฅธ ์ํ(์ฆ, min, max, onUpdate ๋ฑ)์ ์์์ด๋ฏ๋ก ํจ๊ณผ์ ์ ๋ฌํ ํ์๊ฐ ์์ต๋๋ค.
๋ค์์ ์ฝ๋์๋๋ฐ์ค์์ ๋ณผ ์ ์๋ ํจ๊ณผ์ ๋๋ค.
const { min, max, step } = props;
const sliderElement = useRef();
useEffect(() => {
if (!sliderElement.current) {
return;
}
const slider = sliderElement.current;
noUiSlider.create(slider, {
connect: true,
start: [min, max],
step,
range: {
min: [min],
max: [max],
},
});
if (props.onUpdate) {
slider.noUiSlider.on('update', props.onUpdate);
}
if (props.onChange) {
slider.noUiSlider.on('change', props.onChange);
}
}, [sliderElement]);
@WebDeg-Brian ์ ์ฒด CodeSandbox ๋ฐ๋ชจ ์์ด๋ ๋น์ ์ ๋์ธ ์ ์์ต๋๋ค. ์ฃ์กํฉ๋๋ค. ์๋จ ๊ฒ์๋ฌผ์ ์ฐธ์กฐํ์ญ์์ค.
๋๋ ์ผ๋ฐ์ ์ธ "๊ธฐ๋ฅ์ ์ ๋ ๋ณํ์ง ์๋๋ค"๋ผ๋ ์คํด์ ๋ํด ์ฝ๊ฐ์ ๊ธ์ ์ฌ๋ ธ์ต๋๋ค.
https://overreacted.io/how-are-function-components-different-from-classes/
์์ ํ ๊ฐ์ ์ฃผ์ ๋ ์๋์ง๋ง ์ด ๊ท์น๊ณผ ๊ด๋ จ์ด ์์ต๋๋ค.
์๋ ํ์ธ์ @gaearon๋ , ์ฌ๊ธฐ์ ๊ฒ์ํ๋๋ก ์์ฒญํ ์์ ๋๋ค(ํธ์ํฐ์์) :)
๊ธฐ๋ณธ์ ์ผ๋ก ๋ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ฐ์ ํธ๋ฉ ์ ํํฌ๋ก ๋ณํํ๋ ค๊ณ ํฉ๋๋ค.
์ด๊ฒ์ ์์ ์ธ๋ถ/๋ด๋ถ์ ์ด๋ฒคํธ์ ๋ํ ํธ๋ฉ์ผ ๋ฟ์
๋๋ค.
๋ด ๋ฌธ์ ๋ useEffect
์ด ์ํ ๊ฐ( trapped
)์ ์์กด ํ์ง ์์ผ๋ฉด ๋๋๋ก ๋ถ์คํ๋ค๋ ๊ฒ์
๋๋ค.
์ค๋ช
ํ๊ธฐ ์ํด ๋ช ๊ฐ์ง ์๊ฒฌ๊ณผ ๋ก๊ทธ๋ฅผ ์์ฑํ์ต๋๋ค. useTrap.js
ํ์ผ์ ๋ณด๋ฉด ์ฃผ์๊ณผ ๋ก๊ทธ๊ฐ useEffect
๋ฐ preventDefaultHelper
ํจ์์ ์์ต๋๋ค.
๋ด๊ฐ ์๋ ํ, ๊ฐ์ด useEffect
์์ ์์ง ์์ผ๋ฉด ์ข
์์ฑ์ ์ผ๋ถ๊ฐ ์๋์ด์ผ ํฉ๋๋ค(๋ด๊ฐ ํ๋ ธ๋ค๋ฉด ์ ์ ํด ์ฃผ์ธ์).
e.preventDefault
).์ฌ๊ธฐ์์ ๋ช ํํ๊ณ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ์ดํดํ ์ ์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค. ์ถ๊ฐ ์ ๋ณด๋ฅผ ์ ๊ณตํด์ผ ํ๋ ๊ฒฝ์ฐ ์๋ ค์ฃผ์ธ์. ๊ฐ์ฌ ํด์!
์๋ ํ์ธ์ @gaearon ๋ , Twitter์์ ์ ์ํ ๋๋ก ์ฌ๊ธฐ์ ๋ง์ถค ํ ์ ์ถ๊ฐํ๊ณ ์์ต๋๋ค! ์ข ์์ฑ์ ๊ฑด๋ ๋ฐ์ง ์๋ ์ฌ๋ฐ๋ฅธ ๋ชจ์์ ์ฐพ๊ธฐ ์ํด ๊ณ ์ฌํ๊ณ ์์ต๋๋ค.
ํ๋์ ์์๋ก ์ ๊ตํ๊ฒ ์ค๋ช ๋์ด ์์ผ๋ ๋ช ํํ๊ณ ์ดํดํ๊ธฐ ์ฝ๊ฒ ์ค๋ช ํ ์ ์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
์ด๊ฒ์ ํ์ฌ ์ํ์ ๋๋ค: react-async-utils/src/hooks/useAsyncData.ts
๊ธฐ๋ฅ ๊ฐ์
์ฌ์ฉ์๊ฐ ๋น๋๊ธฐ ํธ์ถ, ๊ฒฐ๊ณผ ๋ฐ์ดํฐ ๋ฐ ํ๋ก์ธ์ค์ ์ํ๋ฅผ ์ฒ๋ฆฌํ๋๋ก ๋์ต๋๋ค.
triggerAsyncData
๋ Promise
๋ฅผ ๋ฐํํ๋ getData
ํจ์์ ๋ฐ๋ผ asyncData
์ํ๋ฅผ ๋น๋๊ธฐ์์ผ๋ก ์
๋ฐ์ดํธํฉ๋๋ค. triggerAsyncData
๋ ํจ๊ณผ๋ก ํธ์ถํ๊ฑฐ๋ ํํฌ ์ฌ์ฉ์๊ฐ "์๋์ผ๋ก" ํธ์ถํ ์ ์์ต๋๋ค.
๋์
triggerAsyncData
๋ฅผ ํธ์ถํ๋ ํจ๊ณผ์ ์ข
์์ฑ์ ๋ณธ์ง์ ์ธ ๊ฒ์
๋๋ค. triggerAsyncData
๋ ํจ๊ณผ์ ์ข
์์ฑ์ด์ง๋ง ๋ชจ๋ ๋ ๋๋ง์์ ์์ฑ๋ฉ๋๋ค. ์ง๊ธ๊น์ง์ ์๊ฐ:triggerAsyncData
=> useMemo
/ useCallback
์ ํจ๊ป useMemo
/ useCallback
๋ฅผ ์ฌ์ฉํ๋ฉด ์ฑ๋ฅ ์ต์ ํ์๋ง ์ฌ์ฉํด์ผ ํฉ๋๋ค. AFAIK.triggerAsyncData
๋ฅผ ์ข
์์ฑ์ผ๋ก ์ฌ์ฉํ๋ ๋์ triggerAsyncData
์ ์ข
์์ฑ์ ์ข
์์ฑ์ผ๋ก ์ฌ์ฉ => ์ง๊ธ๊น์ง ์ฐพ์ ์ต์์ ์ต์
. ๊ทธ๋ฌ๋ ๊ทธ๊ฒ์ "exhaustive-deps" ๊ท์น์ ์ด๊น๋๋ค.useMemo
/ useCallback
์ฌ์ฉํ์ฌ ์ ์ ํ ๊ฐ์ ์ ๊ณตํฉ๋๋ค. => ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ทธ๋ค์ด ํ๋ค๋ฉด ๊ทธ๊ฒ์ ์์ฃผ ์ฅํฉํฉ๋๋ค.asyncData
). ์ด๊ฒ์ "exhaustive-deps" ๊ท์น์ ๋ค์ ๊นจ๋จ๋ฆฝ๋๋ค.์๊ฐ๋ณด๋ค ์ค๋ช ์ด ๊ธธ์์ง๋ง... ํํฌ๋ฅผ ์ ๋๋ก ์ฌ์ฉํ์ง ์์ผ๋ ค๋ ๋ ธ๋ ฅ์ด ๋ฐ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ์ด๋ฌํ ์ด๋ ค์์ ๋ช ํํ๊ฒ ํ๊ธฐ ์ํด ์ ๊ฐ ํ ์ ์๋ ๋ค๋ฅธ ์ผ์ด ์์ผ๋ฉด ์๋ ค์ฃผ์ญ์์ค.
์ฌ๊ธฐ์์ ๋ชจ๋ ๋ ธ๋ ฅ์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค!
@gaearon ๋
์ต์ํ์ ๋น๋๊ธฐ์ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ ์์ CodeSandbox ์์ ์ ๋๋ค.
์ฌ์ฉ์๋ json api ์์ ๊ฐ์ ธ์จ 5๊ฐ์ lorem ipsum ์ ๋ชฉ ๋ฌธ์์ด์ ๋ณผ ๊ฒ์ผ๋ก ์์๋ฉ๋๋ค.
์๋ํ API๋ก ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ์ํ ์ฌ์ฉ์ ์ ์ ํํฌ๋ฅผ ๋ง๋ค์์ต๋๋ค.
const { data, isLoading, isError } = useDataApi('https://jsonplaceholder.typicode.com/posts')
์ฌ์ฉ์ ์ ์ useDataApi
ํํฌ์ ๋ด๋ถ:
...
const fetchData = async () => {
let response;
setIsError(false);
setIsLoading(true);
try {
response = await fetch(url).then(response => response.json());
setData(response);
} catch (error) {
setIsError(true);
}
setIsLoading(false);
};
useEffect(
() => {
fetchData();
},
[url]
);
...
๋ฌธ์ ๋ ์ด ์ฝ๋
useEffect(
() => {
fetchData();
},
[url]
);
์ฌ๊ธฐ์ react-hooks/exhaustive-deps
๋ ๋ด ์ข
์์ฑ ๋ฐฐ์ด์ fetchData
๋ฅผ ์ถ๊ฐํ๊ณ url
๋ฅผ ์ ๊ฑฐํด์ผ ํ๋ค๋ ๊ฒฝ๊ณ ๋ฅผ ๋ฐ์์ํต๋๋ค.
์ด ํํฌ๋ฅผ ๋ค์์ผ๋ก ๋ฐ๊พธ๋ฉด
useEffect(
() => {
fetchData();
},
[fetchData]
);
๊ทธ๋ฐ ๋ค์ ์ง์์ ์ผ๋ก ์์ฒญ์ ์คํํ๊ณ ์ ๋ ๋ฉ์ถ์ง ์์ต๋๋ค. ์ด๋ ๋ฌผ๋ก ํฐ ๋ฌธ์ ์
๋๋ค. ๋ด ์ฝ๋์ ๋ฒ๊ทธ๊ฐ ์๋์ง ๋๋ react-hooks/exhaustive-deps
๊ฐ ๊ฐ์์ฑ์ ์คํํ๋์ง ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค.
๋์์ ์ฃผ์๋ฉด ๊ฐ์ฌํ๊ฒ ์ต๋๋ค. ์ ๋ง ๊ณ ๋ง์.
์ถ์ : useEffect๊ฐ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ์ ์ ํฉํ์ง ์๋ค๋ ๊ทํ์ ์๊ฒฌ์ ์ฝ์์ง๋ง, ๋ฐ์ ๋ฌธ์ ๋ useEffect
๋ฐ์ดํฐ๊ฐ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ์ ์ ํฉํ๋ค๋ ํ์ ์ ์ฃผ๋ Data fetching, setting up a subscription, and manually changing the DOM in React components are all examples of side effects
๋ผ๊ณ ์ฃผ์ฅํฉ๋๋ค. ๊ทธ๋์ ์ง๊ธ์ ์กฐ๊ธ ํผ๋์ค๋ฝ์ต๋๋ค ๐
@jan-stehlik fetchData๋ฅผ useCallback์ผ๋ก ๋ํํด์ผ ํฉ๋๋ค. https://codesandbox.io/s/pjmjxprp0m ์์ ํ์ํ ๋ณ๊ฒฝ ์ฌํญ์ผ๋ก ๊ทํ์ ์ฝ๋ ๋ฐ ์์๋ฅผ ๋ถ๊ธฐํ์ต๋๋ค.
๋งค์ฐ ๋์์ด ๋ฉ๋๋ค .
๋ด๊ฐ ์๋ ํ ๊ฐ์ด useEffect ๋ด๋ถ์ ์์ผ๋ฉด ์ข ์์ฑ์ ์ผ๋ถ๊ฐ ์๋์ด์ผ ํฉ๋๋ค(ํ๋ฆฐ ๊ฒฝ์ฐ ์์ ).
๋๋ ๋น์ ์ด ์ฌ๊ธฐ์์ ํ๋ ธ๋ค๊ณ ์๊ฐํฉ๋๋ค. ๋๋ ์คํ๋ ค ์ฝ๊ฐ ํผ๋ ์ค๋ฝ์ต๋๋ค. ๋น์ ์ด ์ฌ์ฉํ๋ handleEvent
๋น์ ์ ํจ๊ณผ ๋ด๋ถ. ๊ทธ๋ฌ๋ ๋น์ ์ ๊ทธ๊ฒ์ ์ ์ธํ์ง ์์ต๋๋ค. ์ด๊ฒ์ด ์ฝ๋ ๊ฐ์ด ์ค๋๋ ์ด์ ์
๋๋ค.
ํฅ๋ฏธ๋ก์ด.
ํจ๊ณผ ๋ด์์ handleEvent๋ฅผ ์ฌ์ฉํ๊ณ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๋น์ ์ ๊ทธ๊ฒ์ ์ ์ธํ์ง ์์ต๋๋ค. ์ด๊ฒ์ด ์ฝ๋ ๊ฐ์ด ์ค๋๋ ์ด์ ์ ๋๋ค.
_"ํ์ง๋ง ๋น์ ์ ๊ทธ๊ฒ์ ์ ์ธํ์ง ์์ต๋๋ค"_์(๋) ๋ฌด์จ ๋ป์ธ๊ฐ์?
ํจ๊ณผ ์๋์ ์ ์ธ๋ฉ๋๋ค(๋ค๋ฅธ ๋ชจ๋ ํธ๋ค๋ฌ์ ๋์ผ).
์๋๋ฉด ํธ๋ค๋ฌ๊ฐ ์ํ ๊ฐ์ ์ฌ์ฉํ๊ณ ํจ๊ณผ๊ฐ ํธ๋ค๋ฌ๋ฅผ ์ฐ๊ฒฐํ๊ธฐ ๋๋ฌธ์ ํจ๊ณผ๊ฐ ํด๋น ์ํ ๊ฐ์ ์์กดํ๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๊น?
์๋๋ฉด ํธ๋ค๋ฌ๊ฐ ์ํ ๊ฐ์ ์ฌ์ฉํ๊ณ ํจ๊ณผ๊ฐ ํธ๋ค๋ฌ๋ฅผ ์ฐ๊ฒฐํ๊ธฐ ๋๋ฌธ์ ํจ๊ณผ๊ฐ ํด๋น ์ํ ๊ฐ์ ์์กดํ๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๊น?
์,์ด ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ์ค ํ๋๋ deps์ ์ ์ธ (๊ทธ ๊ฒฝ์ฐ๋ก ํฌ์ฅํ๋ค useCallback
์ ๋ค์ ํผํ๊ธฐ ์ํด), ๋๋ ๋ชจ๋ ๊ธฐ๋ฅ ์ฌ์ฉ.
์ข์ ์ด๊ฒ์ ๋์๊ฒ ์๋ก์ด ์์์ด๋ค! @gaearon์ ์
๋ ฅํด์ฃผ์
์ ๊ฐ์ฌํฉ๋๋ค :)
๋๋ ๋จ์ง ๊ทธ๊ฒ์ด ๋(๊ทธ๋ฆฌ๊ณ ๋ค๋ฅธ ์ฌ๋๋ค์๊ฒ?)
ํจ๊ณผ๊ฐ ํจ์๋ฅผ ํธ์ถ, ์ ๋ฌ ๋๋ ์ํํ๋ ๊ฒฝ์ฐ ํด๋น deps ๋ฐฐ์ด์ ์ ๋ฌํด์ผ ํฉ๋๋ค.
ํจ์ ์์ฒด ๋๋ ์ด ํจ์๊ฐ ์ฌ์ฉํ๋ ๋ณ์์
๋๋ค.
ํจ์ ๊ตฌ์ฑ ์์/์ฌ์ฉ์ ์ ์ ํํฌ ๋ด์์ ํจ์๊ฐ ์ ์ธ๋ ๊ฒฝ์ฐ ๊ตฌ์ฑ ์์ ๋๋ ์ฌ์ฉ์ ์ ์ ํํฌ๊ฐ ์คํ๋ ๋๋ง๋ค ๋ค์ ์์ฑ๋์ง ์๋๋ก useCallback
๋ก ๊ฐ์ธ๋ ๊ฒ์ด ์ข์ต๋๋ค.
๋๋ ๋ฌธ์์์ ๊ทธ๊ฒ์ ๋ณด์ง ๋ชปํ๋ค๊ณ ๋งํด์ผ ํ๋ค.
_Note_ ์น์
์ ์ถ๊ฐํด๋ ๊ด์ฐฎ์ต๋๊น?
๋ฉ๋ชจ
์ ๋ ฅ ๋ฐฐ์ด์ ํจ๊ณผ ํจ์์ ์ธ์๋ก ์ ๋ฌ๋์ง ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๊ฐ๋ ์ ์ผ๋ก ๊ทธ๊ฒ์ด ๊ทธ๋ค์ด ๋ํ๋ด๋ ๊ฒ์ ๋๋ค. ํจ๊ณผ ํจ์ ๋ด์์ ์ฐธ์กฐ๋๋ ๋ชจ๋ ๊ฐ์ ๋ํ ์ ๋ ฅ ๋ฐฐ์ด์ ๋ํ๋์ผ ํฉ๋๋ค. ๋ฏธ๋์๋ ์ถฉ๋ถํ ๋ฐ์ ๋ ์ปดํ์ผ๋ฌ๊ฐ ์ด ๋ฐฐ์ด์ ์๋์ผ๋ก ์์ฑํ ์ ์์ต๋๋ค.
ํธ์งํ๋ค
ํ ๊ฐ์ง ๋, ๋ด ์์์ handleEvent
(๋๋ ๊ทธ๋ฌํ ์ด์ ๋ก ๋ค๋ฅธ ํธ๋ค๋ฌ)๋ฅผ ๋ํํ ๋ useCallback
๋ํ dep๋ ๋ฌด์์
๋๊น? event
์์ฒด์ธ๊ฐ์?
๋๋ ๋ฌธ์์์ ๊ทธ๊ฒ์ ๋ณด์ง ๋ชปํ๋ค๊ณ ๋งํด์ผ ํ๋ค.
๋ฌธ์์๋ "ํจ๊ณผ ํจ์ ๋ด์์ ์ฐธ์กฐ๋๋ ๋ชจ๋ ๊ฐ์ด ์ ๋ ฅ ๋ฐฐ์ด์๋ ๋ํ๋์ผ ํฉ๋๋ค"๋ผ๊ณ ๋์ ์์ต๋๋ค. ๊ธฐ๋ฅ๋ ๊ฐ์น์ ๋๋ค. ๋๋ ์ฐ๋ฆฌ๊ฐ ์ด๊ฒ์ ๋ ์ ๋ฌธ์ํํด์ผ ํ๋ค๋ ๋ฐ ๋์ํฉ๋๋ค. ์ด๊ฒ์ด ์ด ์ค๋ ๋์ ์ ๋ถ์ ๋๋ค :-) ๋๋ ์ด๊ฒ์ ๊ดํ ์ ๋ฌธ์ ํ์ด์ง์ ๋ํ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ์์งํ๊ณ ์์ต๋๋ค.
ํ ๊ฐ์ง ๋, ๋ด ์์์ handleEvent(๋๋ ๊ทธ๋ฌํ ์ด์ ๋ก ๋ค๋ฅธ ํธ๋ค๋ฌ)๋ฅผ ๋ํํ ๋ useCallback์ dep๋ ๋ฌด์์ ๋๊น? ์ด๋ฒคํธ ์์ฒด์ธ๊ฐ์?
๋น์ ์ด ๋ฌด์จ ๋ป์ธ์ง ํ์คํ์ง. ํจ์ ์ธ๋ถ์์ ์ฐธ์กฐํ๋ ๋ชจ๋ ๊ฐ์
๋๋ค. useEffect
์์์ฒ๋ผ.
๋๋ ์ด๊ฒ์ ์ข ์์ฑ์ผ๋ก ํจ์๋ก ์๊ฐํ์ง ์์๋ค๊ณ ์๊ฐํฉ๋๋ค. ๋ด ์ ์ ๋ชจ๋ธ์ด ์๋ชป๋์์ต๋๋ค. ๋ด ๊ตฌ์ฑ ์์ / ํํฌ์ ์ํ์ด๋ ์ธ์๋ก ๋ค์ด์จ ๊ฒฝ์ฐ์๋ง ์ข ์์ฑ์ผ๋ก ํจ์๋ฅผ ์ ๋ฌํ๋ ๊ฒ์ฒ๋ผ ์๊ฐํ์ต๋๋ค. ์ ๋ฅผ ์ํด ์ด๊ฒ์ ๋ช ํํ ํด ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค.
useCallback
์ ๊ดํด์๋ ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ์ต๋๋ค.
const memoHandleEvent = useCallback(
handleEvent
);
๋ฌผ๋ก ์ ๋ฌ memoHandleEvent
ํ๋ ์ข
์์ฑ useEffect
์ฐ์ ๊ดํด์ addEventListener
INSEAD ์ค์ ์ handleEvent
๊ธฐ๋ฅ. ์๋ํ๋ ๊ฒ ๊ฐ์ผ๋ฉด ์ด๊ฒ์ด ์ ์ ํ๊ณ ๊ด์ฉ์ ์ธ ๋ฐฉ๋ฒ์ด๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
์ฐธ๊ณ ๋ ๋ฒ์งธ ์ธ์๊ฐ ์๋ useCallback
๋ ์๋ฌด ์์
๋ ์ํํ์ง ์์ต๋๋ค.
๋ค์ ๋งํ์ง๋ง ์์ ํ ์๋๋ฐ์ค๊ฐ ํ์ํฉ๋๋ค. ์ด์ ๊ฐ์ ๋ถ์์ ํ ์ค๋ช ์ผ๋ก ์์ ์ฌํญ์ด ์ฌ๋ฐ๋ฅธ์ง ์ฌ๋ถ๋ฅผ ์ ์ ์์ต๋๋ค.
๋ ๋ฒ์งธ ์ธ์๊ฐ ์๋ useCallback์ ์๋ฌด ์์ ๋ ์ํํ์ง ์์ต๋๋ค.
์๋ฅด๊ทธ! :์ฐก๊ธ:ใ ใ ใ
๋ค์ ๋งํ์ง๋ง ์์ ํ ์๋๋ฐ์ค๊ฐ ํ์ํฉ๋๋ค. ์ด์ ๊ฐ์ ๋ถ์์ ํ ์ค๋ช ์ผ๋ก ์์ ์ฌํญ์ด ์ฌ๋ฐ๋ฅธ์ง ์ฌ๋ถ๋ฅผ ์ ์ ์์ต๋๋ค.
์, ์ด๊ฒ์ ์์์ ๋์ผํ ๋งํฌ ์ ๋๋ค. ๋ฐฉ๊ธ ์ ๋ฐ์ดํธํ์ต๋๋ค :)
CodeSandbox ๋งํฌ๋ฅผ ์ ๋ฐ์ดํธํ์ง ๋ง์ญ์์ค. PI๋ ์๋ ๊ทธ๋๋ก ํ์ํฉ๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ๋งํฌ์ ๋ํ ๋ฆฐํธ ๊ท์น์ ํ ์คํธํ ์ ์์ต๋๋ค. ๋ ๊ฐ์ ๋ค๋ฅธ ์๋ฃจ์ ์ด ์๋ ๊ฒฝ์ฐ ๋ ๊ฐ์ ๋ณ๋ ์๋๋ฐ์ค๋ฅผ ๋ง๋ค ์ ์์ต๋๊น? ๊ทธ๋์ ํ๋ํ๋ ํ์ธํ ์ ์์ด์.
์ด๋จธ ๋ฏธ์ํฉ๋๋ค! :PI๊ฐ ๋ด ๊ณ์ ์ ์๋๋ฐ์ค ์๋ฅผ ์ด๊ณผํ์ต๋๋ค. ์ผ๋ถ๋ฅผ ์ญ์ ํ๊ณ ๋ค๋ฅธ ๊ฒ์ ์์ฑํ๊ฒ ์ต๋๋ค(๊ทธ๋ฆฌ๊ณ ์๋ณธ์ ๋ณ๊ฒฝ ์ฌํญ์ ๋๋๋ฆฝ๋๋ค).
@gaearon useCallback
์๋ฃจ์
์ ๋ํ ๋ ๋ฒ์งธ ๋งํฌ์
๋๋ค.
๊ด์ฐฎ๋ค๊ณ ์๊ฐํ๋ ์๋๋ฆฌ์ค๊ฐ ์์ง๋ง ๋ฆฐํฐ๊ฐ ๋ถํํฉ๋๋ค. ๋ด ์ํ:
์ํ์ด ๋ํ๋ด๋ ค๋ ๊ฒ์ ์ฌ์ฉ์๊ฐ ๋ฒํผ์ ํด๋ฆญํ ๋ ์ด์ ์ ์ ๊ณต๋ Id ๋ฐ ํจ์๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ ๋ฐ์ดํฐ๋ฅผ ์์ฒญํ๋๋ก ์์ฒญํ๋ ๊ฒ์ ๋๋ค. Id๊ฐ ๋ณ๊ฒฝ๋๋ฉด ์ ๋ฐ์ดํฐ๋ฅผ ์์ฒญํ์ง ์์์ผ ํฉ๋๋ค. ๋ค์ ๋ก๋๋ฅผ ์ํ ์ ์์ฒญ๋ง ์ ๋ฐ์ดํฐ ์์ฒญ์ ํธ๋ฆฌ๊ฑฐํด์ผ ํฉ๋๋ค.
์ฌ๊ธฐ์ ์๋ ์ฝ๊ฐ ์ธ์์ ์ ๋๋ค. ๋ด ์ค์ ์์ฉ ํ๋ก๊ทธ๋จ์์ React๋ ํจ์ฌ ๋ ํฐ ์น ์์ฉ ํ๋ก๊ทธ๋จ์ ์์ ๋ถ๋ถ์ธ DIV์ ์์ต๋๋ค. ์ ๋ฌ๋๋ ํจ์๋ Redux ๋ฐ mapDispatchToProps๋ฅผ ํตํด ์ด๋ฃจ์ด์ง๋ฉฐ, ์ฌ๊ธฐ์ ์์ ์์ฑ์ Id๋ฅผ ์ฌ์ฉํ๊ณ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ณ ์ ์ฅ์๋ฅผ ์ ๋ฐ์ดํธํ๊ธฐ ์ํด ajax ์์ฒญ์ ํฉ๋๋ค. refreshRequest ์ํ์ React.createElement๋ฅผ ํตํด ์ ๋ฌ๋ฉ๋๋ค. ์๋ ๊ตฌํ์์๋ ํด๋์ค ๊ตฌ์ฑ ์์์ ๋ค์๊ณผ ๊ฐ์ ์ฝ๋๊ฐ ์์์ต๋๋ค.
componentDidUpdate (prevProps) {
const { getData, someId, refreshRequest} = this.props;
if (prevProps.refreshRequest!== this.props.refreshRequest) {
getData(someId);
}
}
ํจ๊ณผ ํํฌ๋ฅผ ์ฌ์ฉํ์ฌ ๋์ผํ ๋์์ ๊ตฌํํ๋ ค๊ณ ํฉ๋๋ค. ๊ทธ๋ฌ๋ ์ํ์ ์ฐ์ฌ์ง ๊ฒ์ฒ๋ผ ๋ฆฐํฐ๋ ๋ค์๊ณผ ๊ฐ์ด ๋ถํํฉ๋๋ค.
๊ฒฝ๊ณ React Hook useEffect์ 'getData' ๋ฐ 'someId' ์ข ์์ฑ์ด ๋๋ฝ๋์์ต๋๋ค. ํฌํจํ๊ฑฐ๋ ์ข ์์ฑ ๋ฐฐ์ด์ ์ ๊ฑฐํ์ญ์์ค.
๋ฆฐํฐ๊ฐ ์ํ๋ ๋ชจ๋ ๊ฒ์ ์ถ๊ฐํ๋ฉด ์ฌ์ฉ์๊ฐ ์ํ useEffect์์ ๋ฒํผ ์ค ํ๋๋ฅผ ํด๋ฆญํ๋ฉด ํธ๋ฆฌ๊ฑฐ๋ฉ๋๋ค. ๊ทธ๋ฌ๋ ์ ๋ฐ์ดํฐ ์์ฒญ ๋ฒํผ์ ๋๋ ์ ๋๋ง ํธ๋ฆฌ๊ฑฐ๋๊ธฐ๋ฅผ ์ํฉ๋๋ค.
์๋ฏธ๊ฐ ์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค. ๋ถ๋ถ๋ช ํ ๋ถ๋ถ์ด ์๋ค๋ฉด ๋ ๋ช ํํ ํ๊ณ ์ ํฉ๋๋ค. ๊ฐ์ฌํฉ๋๋ค!
๋ฐฉ๊ธ [email protected]
๋ฅผ ๊ฒ์ํ๋๋ฐ ์ด๋ ๋ฒ ์ด ํจ์ ์ข
์์ฑ์ ๊ฐ์งํ๊ธฐ ์ํ ์คํ์ ์ง์์ด ์์ต๋๋ค( useCallback
์์ด๋ ๊ทธ๋ค์ง ์ ์ฉํ์ง ์์ ๊ฒฝํฅ์ด ์์). ๋ค์์ GIF์
๋๋ค.
์ฌ๋ฌ๋ถ์ ํ๋ก์ ํธ์์ ์๋ํด ๋ณด๊ณ ์ด๋ค ๋๋์ธ์ง ์ ์ ์๋ค๋ฉด ์ข๊ฒ ์ต๋๋ค! (https://github.com/facebook/react/pull/15026์์ ํน์ ํ๋ฆ์ ๋ํด ๋๊ธ์ ๋ฌ์์ฃผ์ธ์.)
๋ด์ผ ์ด ์ค๋ ๋์ ์์ ์์ ์๋ํ ๊ฒ์ ๋๋ค.
์์ง ํด๋ณด์ง๋ ์์์ง๋ง ํธ์ด์คํ
๋ ๊ฐ๋ฅํ์ง ๊ถ๊ธํฉ๋๋ค. ์ด๊ฒ์ ๋ด๊ฐ ๊ทธ ์๋ฆฌ์์ ์๊ฐํด๋ธ "์ต์ ์"์ผ ๋ฟ์ด๋ฏ๋ก ์๋ฌด ์ธ๋ชจ๊ฐ ์์ง๋ง return
๋ฌธ์ ๋ ์ฝ๊ฒ ๋ณผ ์ ์๋๋ก ํธ์ด์คํธ ์ ์ธ์ ๋ง์ด ์ฌ์ฉํฉ๋๋ค.
function Component() {
useEffect(() => {
handleChange
}, [handleChange])
return null
function handleChange() {}
}
๋ฆฐํฐ์ ๊ดํ ํ useEffect
์ฒ๋ผ ์๋ํ๋๋ก ๋ค๋ฅธ ๊ธฐ๋ฅ์ ๊ตฌ์ฑํ๋ ์ต์
์ด ๊ท์น์ ์์ผ๋ฉด ์ข์ ๊ฒ์
๋๋ค. ์๋ฅผ ๋ค์ด, AJAX ํธ์ถ์ ์ํํ๋ ํจ๊ณผ์ ๋ํด ๋น๋๊ธฐ ํจ์๋ฅผ ์ฝ๊ฒ ์ฌ์ฉํ ์ ์๋๋ก ์ด๊ฒ์ ์ถ๊ฐํ์ต๋๋ค. ๊ทธ๋ฌ๋ ์ด์ ๊ฐ์ด ๋ชจ๋ exhaustive-deps
linting ์ด์ ์ ์๊ฒ ๋ฉ๋๋ค.
const useAsyncEffect = (fn, ...args) => {
/* eslint-disable react-hooks/exhaustive-deps */
useEffect(() => {
fn();
}, ...args);
};
ํธ์ง: ์ ๊ฒฝ์ฐ์ง ๋ง์ธ์. ๊ท์น์ additionalHooks
์ต์
์ ์ฌ์ฉํ์ฌ ์ด๊ฒ์ด ์ด๋ฏธ ๊ฐ๋ฅํ๋ค๋ ๊ฒ์ ์์์ต๋๋ค.
์๋
ํ์ธ์ ์ฌ๋ฌ๋ถ,
https://codesandbox.io/s/znnmwxol7l ์ ์๊ฐ
์๋๋ ๋ด๊ฐ ์ํ๋ ๊ฒ์ ๋๋ค.
function App() {
const [currentTime, setCurrentTime] = React.useState(moment());
const currentMonth = React.useMemo(
() => {
console.log("RUN");
return currentTime.format("MMMM");
},
[currentTime.format("MMMM")] // <= this proplem [currentTime]
);
return (
<div className="App">
<h1>Current month: {currentMonth}</h1>
<div>
<button
onClick={() => setCurrentTime(currentTime.clone().add(1, "days"))}
>
+ 1 day
</button>
</div>
<div>{currentTime.toString()}</div>
</div>
);
}
๊ทธ๋ฌ๋ ์ด๊ฒ์ด ๋ด๊ฐ ์ป๋ ๊ฒ์ ๋๋ค.
const currentMonth = React.useMemo(
() => {
console.log("RUN");
return currentTime.format("MMMM");
},
[currentTime] // <= this proplem
);
currentTime
๋ณ๊ฒฝ๋ ๋๋ง๋ค currentMonth
์ฌ๊ณ์ฐ ๋ถํ์
๋๋ ์ด๋ป๊ฒ ๋ ์๋์์ ํ ์ ์์ต๋๋ค.
const currentMonth = React.useMemo(
() => {
return currentTime.format("MMMM");
},
[myEqualityCheck(currentTime)]
);
์ด๋ฏธ ๋ต๋ณ์ด ๋์๋ค๋ฉด ์ฃ์กํฉ๋๋ค. ์์ ์ค๋ ๋์์ ๋ณผ ์ ์์ต๋๋ค.
๋ง์ดํธ ์์๋ง useEffect ํํฌ๋ฅผ ์คํํ๋ ๋ฐฉ๋ฒ์ ๋น ์
๋ ฅ ๋ฐฐ์ด์ ๋ ๋ฒ์งธ ๋งค๊ฐ๋ณ์๋ก ์ ์ํ๋ ๊ฒ์
๋๋ค. ๊ทธ๋ฌ๋ ๊ทธ๋ ๊ฒ ํ ๋ ์ฒ ์ ํ deps๋ ํด๋น ์
๋ ฅ ์ธ์๋ฅผ ํฌํจํ๋ ๊ฒ์ ๋ํด ๋ถ๋ง์ ํ์ํฉ๋๋ค. ๊ทธ๋ฌ๋ฉด ์
๋ฐ์ดํธ ์์๋ ์คํ๋๋๋ก ํจ๊ณผ๊ฐ ๋ณ๊ฒฝ๋ฉ๋๋ค.
์ฒ ์ ํ deps๊ฐ ํ์ฑํ๋ ๋ง์ดํธ์์๋ง useEffect๋ฅผ ์คํํ๋ ์ ๊ทผ ๋ฐฉ์์ ๋ฌด์์
๋๊น?
@einarq ๋ด ์๊ฐ์๋ on-mount useEffect
๋ชจ๋ ์ฐธ์กฐ ๊ฐ์ด ์ ๋ ๋ณ๊ฒฝ๋์ง ์๋๋ก ํด์ผ ํฉ๋๋ค. useMemo
์ ๊ฐ์ ๋ค๋ฅธ ํํฌ๋ฅผ ์ฌ์ฉํ์ฌ ๋ฌ์ฑํ ์ ์์ต๋๋ค. ๊ทธ ํ์๋ ์ด ESlint ๊ท์น์ด ๋ชจ๋ ์ฐธ์กฐ๋ฅผ ๋ฐฐ์ด์ ์ถ๊ฐํ๋์ง ์ฌ๋ถ์ ๊ด๊ณ์์ด(์๋ ์์ ํฌํจ) ์ฝ๋๋ ํ ๋ฒ๋ง ์คํ๋ฉ๋๋ค.
@einarq ์ค๋ ๋์ ๋ค๋ฅธ ๊ณณ์์ ์ธ๊ธํ๋ฏ์ด
@nghiepit ๋น์ ์ ์๋ ๋์๊ฒ ์ ๋ง ์๋ฏธ๊ฐ ์์ต๋๋ค. ์
๋ ฅ์ด currentTime.format("MMMM")
์ด๋ฉด useMemo
๋ ์ด๋ฏธ ๊ณ์ฐ ํ๊ธฐ ๋๋ฌธ์ ์๋ฌด ๊ฒ๋ ์ต์ ํํ์ง ์์ต๋๋ค. ๋ฐ๋ผ์ ๋ถํ์ํ๊ฒ ๋ ๋ฒ ๊ณ์ฐํ๊ณ ์์ต๋๋ค.
additionalHooks
์ต์
์ ์ฝ๋ฐฑ์ธ ์ธ์ ์ธ๋ฑ์ค๋ฅผ ์ง์ ํ ์ ์์ต๋๊น? ๋๋ ๊ทธ๊ฒ์ด ์ฒซ ๋ฒ์งธ https://github.com/facebook/react/blob/9b7e1d1389e080d19e71680bbbe979ec58fa7389/packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js# ๊ฐ ๋ ๊ฒ์ด๋ผ๊ณ ์ง๊ธ ์ฝ๋์์ ๊ฐ์ ํ๊ณ ์์์ ์์์ต๋๋ค. L1081
ํ์ฌ ๋ถ๊ฐ๋ฅํฉ๋๋ค. ์ฐ๋ฆฌ์ ์ผ๋ฐ์ ์ธ ์ง์นจ์ ์ฌ์ฉ์ ์ ์ Hooks๊ฐ deps
์ธ์๋ฅผ ๊ฐ์ง ์๋ ๊ฒ์ ์ ํธํด์ผ ํ๋ค๋ ๊ฒ์
๋๋ค. ์๋ํ๋ฉด deps๊ฐ ๊ตฌ์ฑ๋๋ ๋ฐฉ์์ ๋ํด ์๊ฐํ๊ธฐ๊ฐ ๋งค์ฐ ์ด๋ ค์์ง๊ธฐ ๋๋ฌธ์
๋๋ค. ํจ์๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ๋์ ์ฌ์ฉ์์๊ฒ useCallback
๋ฅผ ์์ฒญํ ์ ์์ต๋๋ค.
@CarlosGines OP ๊ฒ์๋ฌผ์์ ์์ฒญํ ๋๋ก CodeSandbox๋ฅผ ๋ง๋ค ์ ์์ต๋๊น? ์ด์ ๋ฅผ ๋ฌป๋ ๊ฒ์ ๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ๋ณ๊ฒฝ ์ฌํญ์ ํ์ธํ๊ธฐ ์ด๋ ต์ต๋๋ค. ํนํ TypeScript๋ก ์์ฑ๋ ๊ฒฝ์ฐ.
๋ ์ ์ฉํ ๋ฉ์์ง์ ๋ ๋๋ํ ํด๋ฆฌ์คํฑ์ผ๋ก [email protected]
๋ฅผ ๊ฒ์ํ์ต๋๋ค. ํ๋ก์ ํธ๊ฐ ์์ ํ๋๊ธฐ ์ ์ ์๋ํด ๋ณด์ญ์์ค.
์ด ์ค๋ ๋์ ๋๋ถ๋ถ์ ์์ ์์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐ ๋์์ด ๋๋ ํฉ๋ฆฌ์ ์ธ ์กฐ์ธ์ ์ ๊ณตํ ๊ฒ์ผ๋ก ๊ธฐ๋ํฉ๋๋ค.
[email protected]
์ด์ด์ผ ํฉ๋๊น?
์.
์ค์ ๋ก ๋ช ๊ฐ์ง ์์ ๋ณ๊ฒฝ ์ฌํญ์ด ํฌํจ๋ [email protected]
์ ๊ฒ์ํ์ต๋๋ค.
@gaearon ํน์ eslint
์ด ์ฝ๋์๋๋ฐ์ค ์์์ ์๋ํ๊ฒ ํด์ฃผ์
จ๋์?
@einarq ์๋ง๋ ์ด์ ๊ฐ์ ๊ฒ์ด ์๋ํ ๊น์?
const useDidMount = fn => {
const callbackFn = useCallback(fn)
useEffect(() => {
callbackFn()
}, [callbackFn])
}
๋๋ ์ค์ ๋ก ํ๋ฌ๊ทธ์ธ์ด ๊ฐ๋จํ CRA ์ฑ์์ ์๋ํ๋๋ก ํ ์ ์๋ค๊ณ ๋งํ๊ธฐ ๋ถ๋๋ฝ์ต๋๋ค( ๋ด ์ค๋ํซ ๊ธฐ๋ฐ).
๋ค์์ ์ฝ๋์๋๋ฐ์ค์์ ๋ถ๊ธฐ ๋ ๋ฆฌํฌ์งํ ๋ฆฌ์
๋๋ค.
๋ฌธ์ ์์ ์ด ๋ฉ๋ชจ๋ฅผ ๋ณด์์ต๋๋ค.
์ฐธ๊ณ : Create React App์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ์ด ๊ท์น์ ์ง์ ์ถ๊ฐํ๋ ๋์ ํด๋น ๊ท์น์ ํฌํจํ๋ react-script์ ๋ฆด๋ฆฌ์ค๋ฅผ ๊ธฐ๋ค๋ฆฌ์ญ์์ค.
๊ทธ๋ฐ๋ฐ ์ง๊ธ์ CRA๋ก ํ ์คํธ ํ ์ ์๋ ๋ฐฉ๋ฒ์ด ์๋์? ๐
๋ค, ESLint ๊ตฌ์ฑ์ ์ถ๊ฐํ ๋๊น์ง ๊บผ๋ด์ ์ถ๊ฐํด์ผ ํฉ๋๋ค. ๋ถ๊ธฐ์์ ๊บผ๋ด๊ณ ๋ณํฉํ์ง ์์ ์ ์์ต๋๋ค. :-)
์๋ ํ์ธ์,
์ฐ์ : ์ปค๋ฎค๋ํฐ ๋ฐ ์ผ๋ฐ์ ์ผ๋ก ํ๊ณ ์๋ ๋๋ผ์ด ์์ ๊ณผ ๊ธด๋ฐํ๊ฒ ํ๋ ฅํด ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค!
Fetch
API๋ฅผ ์ค์ฌ์ผ๋ก ๊ตฌ์ถํ ์ฌ์ฉ์ ์ง์ ํํฌ์ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. ์ด ๋ฌธ์ ๋ฅผ ๋ณด์ฌ์ฃผ๊ธฐ ์ํด Codesandbox๋ฅผ ๋ง๋ค์์ต๋๋ค.
https://codesandbox.io/s/kn0km7mzv
์ฐธ๊ณ : ๋ฌธ์ (์๋ ์ฐธ์กฐ)๋ก ์ธํด ๋ฌดํ ๋ฃจํ๊ฐ ๋ฐ์ํ๊ณ ๋ฌธ์ ๋ฅผ ์์ฐํ๋ ๋ฐ ์ฌ์ฉํ๋ DDoS jsonplaceholder.typicode.com
๋ฅผ ์ํ์ง ์์ต๋๋ค. ๋ฐ๋ผ์ ์นด์ดํฐ๋ฅผ ์ฌ์ฉํ๋ ๊ฐ๋จํ ์์ฒญ ์ ํ๊ธฐ๋ฅผ ํฌํจํ์ต๋๋ค. ์ด๊ฒ์ ๋ฌธ์ ๋ฅผ ์์ฐํ๊ธฐ ์ํด ํ์ํ์ง๋ ์์ง๋ง ์ด ํ๋ฅญํ ํ๋ก์ ํธ์ ๋ฌด์ ํ์ ์์ฒญ์ ์คํํ๋ ๊ฒ์ ์๋ชป๋์๋ค๊ณ ๋๊ผ์ต๋๋ค.
์์ด๋์ด๋ API ์์ฒญ์ 3๊ฐ์ง ๊ฐ๋ฅํ ์ํ์ธ ๋ก๋, ์ฑ๊ณต ๋ฐ ์ค๋ฅ๋ฅผ ๋ณด๋ค ์ฝ๊ฒ โโ์ฒ๋ฆฌํ ์ ์๋๋ก ํ๋ ๊ฒ์
๋๋ค. ๋ฐ๋ผ์ isLoading
, response
๋ฐ error. It makes sure that either
์๋ต or
์ค๋ฅ is set and updates
3๊ฐ ์์ฑ์ ๋ฐํํ๋ ์ฌ์ฉ์ ์ ์ ํํฌ useFetch()
๋ฅผ ๋น๋ํ์ต๋๋ค response
is set and updates
isLoading . As the name implies, it uses the
Fetch` API.
์ด๋ฅผ ์ํด 3๊ฐ์ useState
ํํฌ๋ฅผ ์ฌ์ฉํฉ๋๋ค.
const [isLoading, setIsLoading] = useState(false);
const [response, setResponse] = useState(null);
const [error, setError] = useState(null);
useEffect
ํํฌ:
useEffect(
() => {
fetch(url, fetchConfig)
.then(/* Handle fetch response... See Codesandbox for the actual implementation */)
},
[url]
);
๊ทธ๊ฒ์ ์ค๋ซ๋์์ ์ข
์ ๋ฐฐ์ด๋ก๋ก ๋ฒ๊ธ์ ์๋ useEffect
๋ง ํฌํจ [url]
. fetchConfig
(= [url, fetchConfig]
)๋ฅผ ์ถ๊ฐํ๋ฉด ๋ฌดํ ๋ฃจํ๊ฐ ๋ฐ์ํฉ๋๋ค. ์ฐ๋ฆฌ์ ํน์ ์ฌ์ฉ ์ฌ๋ก์ ๊ฒฝ์ฐ url
๋ณ๊ฒฝ๋์์ง๋ง ๋ฆฐํฐ๊ฐ [url]
( v1.4.0
๋ฐ v1.5.0-beta.1
).
์ฌ์ฉ์ ์ ์ ํํฌ๊ฐ ๋๋๋ฉด 3๊ฐ์ ์ํ ๋ณ์๊ฐ ๊ฐ์ฒด๋ก ๋ฐํ๋ฉ๋๋ค.
return {
error,
isLoading,
response
};
Linting ์ ์์ด ํ๋นํ๊ธฐ ๋๋ฌธ์ ์ด๊ฒ์ด ์ด ๋ฌธ์ ์ ๋ํ ์ง์นจ์ ์์ฒญํ๊ธฐ์ ์ ํฉํ ๊ณณ์ธ์ง ํ์คํ์ง ์์ต๋๋ค. ๊ทธ๋ ์ง ์๋ค๋ฉด ์ฃ์กํฉ๋๋ค.
fetchConfig
๋ณ๊ฒฝ๋๋ฉด ์ด๋ป๊ฒ ๋๋์? ์ ์ ์ผ ๊ฒ์ผ๋ก ์์ํ๋ ์ด์ ๋ ๋ฌด์์
๋๊น?
๊ด์ฐฎ์. ์ง๋ ์ฃผ์ ์์ ์ฌํญ ๋ฐ ๊ฐ์ ์ฌํญ๊ณผ ํจ๊ป [email protected]
๋ฅผ ์ถ์ํ์ต๋๋ค.
์ด ์ค๋ ๋๋ ๋ฌธ์ ๋ฅผ ์ผ์ผํค๋ ๋ค์ํ ํจํด์ ์ฐพ๋ ๋ฐ ํฐ ๋์์ด ๋์์ต๋๋ค.
์ฌ๋ฌ๋ถ๊ป ์ง์ฌ์ผ๋ก ๊ฐ์ฌ๋๋ฆฝ๋๋ค. (ํนํ ์๋๋ฐ์ค๋ฅผ ์ ๊ณตํด์ฃผ์ ๋ถ๋ค. :-)
๊ฒฝ์ฐ๊ฐ ๋ง๊ธฐ ๋๋ฌธ์ ์ผ์ผ์ด ์ผ์ผ์ด ์ผ์ผ์ด ์ผ์ผ์ด ์์ธํ ๋ต๋ณ๋๋ฆฌ์ง๋ ์๊ฒ ์ต๋๋ค.
๋์ , ์ฐ๋ฆฌ๋ ์์ผ๋ก ๋ฉฐ์น ์์ ์ผ๋ฐ์ ์ธ ์กฐ๋ฆฌ๋ฒ๊ณผ ๋ฌธ์ ๋ฅผ ์์ฑํ๊ณ ๋ฌธ์์์ ๋งํฌํ ๊ฒ์ ๋๋ค. ์ด ์ค๋ ๋์ ๋ชจ๋ ์ผ๋ฐ์ ์ธ ํจํด์ด ํฌํจ๋๋์ง ํ์ธํฉ๋๋ค(๋๋ ๋๋ฌธ ํจํด์ ๋ํด์๋ ๋ณ๋์ ๋ฌธ์ ์์ ํ์ ์กฐ์น๋ฅผ ์์ฒญํ์ญ์์ค).
์์ ๊ฐ ๊ฒ์๋๋ฉด ์ฌ๊ธฐ์ ์ฃผ์์ ๋ฌ๊ณ ์ฌ๋ฐ๋ฅธ ์์ ์ ๋ณด์ฌ์ฃผ๋ ๊ด๋ จ ๋ต๋ณ/์์ ์ ๋ํ ๋งํฌ๋ฅผ ์ถ๊ฐํ์ฌ CodeSandbox๊ฐ ํฌํจ๋ ๋ชจ๋ ์ฃผ์์ ํธ์งํ๊ฒ ์ต๋๋ค. ์ด๊ฒ์ด ๋น์ ๊ณผ ๋ฏธ๋์ ๋ ์๋ค์๊ฒ ๋์์ด ๋๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
๊ฑด๋ฐฐ!
โค๏ธ
@timkraut ๋ deps์ fetchConfig
๋ฅผ ์ถ๊ฐํ ์ ์์ด์ผ ํ๊ณ ๊ตฌ์ฑ ์์๋ ์ฐธ์กฐ๊ฐ ์ ์ง๋๋๋ก ๋ฉ๋ชจ๋ก ๊ฐ์ธ์ผ ํฉ๋๋ค.
์: https://codesandbox.io/s/9l015v2x4w
์ด๊ฒ์ ๋ํ ๋ด ๋ฌธ์ ๋ ์ด์ ๊ตฌ์ฑ ์์๊ฐ ํํฌ์ ๊ตฌํ ์ธ๋ถ ์ฌํญ์ ๋ํด ์๊ณ ์์ด์ผ ํ๋ค๋ ๊ฒ์ ๋๋ค...
์ด ์ค๋ ๋๊ฐ ์ฌ์ ํ ์์ ํ ๋ก ์ ์ด๋ ค ์๋์ง ํ์คํ์ง ์์ง๋ง ์ฌ์ ํ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ์ค์ฌ์ผ๋ก ๋จธ๋ฆฌ๋ฅผ ๊ฐ์ธ๊ณ ์์ต๋๋ค. ๋ด ์ง๋ฌธ์ useEffect ํํฌ๊ฐ ์ข ์์ฑ ๋ฐฐ์ด๊ณผ ํจ๊ป ์คํ๋๋ ์์ ์ ์ ์ดํ๊ณ ํด๋น ์์ ์ ๊ฐ์ ์ฌ์ฉํ๋ ๊ฒ๊ณผ ๋ฆฐํธ ๊ท์น์ ์ฐํํ๊ธฐ ์ํด ๋ณ๋์ ์ฐธ์กฐ๋ฅผ ์ ์ธํด์ผ ํ๋ ๊ฒ์ ๊ดํ ๊ฒ์ ๋๋ค.
https://codesandbox.io/s/40v54jnkyw
์ด ์์์๋ ์ฃผ๊ธฐ์ ์ผ๋ก ์ ๋ ฅ ๊ฐ์ ์๋ ์ ์ฅํ๋ ค๊ณ ํฉ๋๋ค.
5์ด๋ง๋ค ์ฝ๋๋ ํ์ฌ ๊ฐ์ ์๋ ์ ์ฅํ๋ ค๊ณ ํฉ๋๋ค(์ง๊ธ์ ํ๋ฉด์ ์ถ๋ ฅํ๊ธฐ๋ง ํ๋ฉด ๋จ). ๋ฆฐํฐ๋ ํจ๊ณผ๊ฐ ๋ฐ์ํ๋ ๋น๋๋ฅผ ๋ณ๊ฒฝํ๋ ์ข ์์ฑ ๋ฐฐ์ด์ ๋ชจ๋ ์ ๋ ฅ ๊ฐ์ ํฌํจํด์ผ ํฉ๋๋ค.
useEffect(
() => {
if (autoSaveTick % 5 === 0) {
setAutosaveValue(
`${input1Value.value}, ${input2Value.value}, ${input3Value.value}`
);
}
},
[autoSaveTick]
);
๋ด๊ฐ ๋ณด๋ ๋์์ ์ ์๋ useTick
๋ฐ useInterval
ํํฌ์ ์ ์ฌํ ๊ตฌํ์ ๊ฐ๋ ๊ฒ์
๋๋ค. ์ฌ๊ธฐ์ ref์ ํ ๋น๋ ์ฝ๋ฐฑ์ด ์์ต๋๋ค. ๋ฆฐํธ ๊ท์น์ ๋ง์ถ๊ธฐ ์ํด ๋ถํ์ํ ํจ์ ์ฌ์ ์๋ฅผ ์ผ์ผํฌ ๊ฒ ๊ฐ์ต๋๋ค.
์ด์ ๋ณ์ ๋ณ๊ฒฝ(๋ณ์ A) ์ ๋ค๋ฅธ ๋ณ์ ๊ฐ(๋ณ์ B ๋ฐ ๋ณ์ C)์ ์ฌ์ฉํ๋ ํ๋์ ๋ณ์(๋ณ์ A)๊ฐ ๋ณ๊ฒฝ๋ ๋ ์คํ๋๋ ํจ๊ณผ๋ฅผ ์์ฑํ๋ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ์ฐพ๊ณ ์์ต๋๋ค.
fetchConfig
๋ณ๊ฒฝ๋๋ฉด ์ด๋ป๊ฒ ๋๋์? ์ ์ ์ผ ๊ฒ์ผ๋ก ์์ํ๋ ์ด์ ๋ ๋ฌด์์ ๋๊น?
์ข ์์ฑ ๋ฐฐ์ด์ ์ถ๊ฐํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ์ฐ๋ฆฌ์ ํน์ ๋น์ฆ๋์ค ์ฌ๋ก์์ ์ด๊ฒ์ ์ ๋ ์ผ์ด๋ ์ ์์ง๋ง ์ด์จ๋ ์ถ๊ฐํ๋ ๊ฒ์ด ์ข์ ์๊ฐ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
์ด๊ฒ์ ๋ํ ๋ด ๋ฌธ์ ๋ ์ด์ ๊ตฌ์ฑ ์์๊ฐ ํํฌ์ ๊ตฌํ ์ธ๋ถ ์ฌํญ์ ๋ํด ์๊ณ ์์ด์ผ ํ๋ค๋ ๊ฒ์ ๋๋ค...
๊ทธ๊ฒ์ด ๋ฐ๋ก ์ฐ๋ฆฌ๊ฐ ๊ฐ์ง๊ณ ์๋ ๋ฌธ์ ์ด๊ธฐ๋ ํฉ๋๋ค./ ์ฐ๋ฆฌ ๊ตฌํ์์๋ ๋ณธ๋ฌธ์ ๋ ์ฝ๊ฒ ์ค์ ํ๊ธฐ ์ํด ์ถ๊ฐ ์์ฑ์ ์ฌ์ฉํ๋ฏ๋ก ์ด ํํฌ๋ฅผ ์ฌ์ฉํ ๋๋ง๋ค 2๊ฐ์ useMemo()
ํธ์ถ์ ์ฌ์ฉํด์ผ ํฉ๋๋ค. ์ด ํ๊ณ๋ฅผ ๊ทน๋ณตํ๋ ๋ฐฉ๋ฒ์ ์์ง ํ์คํ์ง ์์ต๋๋ค. ์์ด๋์ด๊ฐ ์์ผ๋ฉด ์๋ ค์ฃผ์ธ์!
๋น ๋ฐฐ์ด์ ์ ๋ฌํ ๋ ๊ท์น์ด ๋ถํํ์ง ์๊ณ ์ข ์์ฑ์ด ํ ๋ฒ๋ง ์๋ useEffect๋ฅผ ์ด๋ป๊ฒ ์คํํ ์ ์์ต๋๊น?
๋ค์๊ณผ ๊ฐ์ด ๋งํ์ญ์์ค.
useEffect(() => {
init({ dsn, environment})
}, [])
์ด๊ฒ์ ๋ํ ๋ด ๋ฌธ์ ๋ ์ด์ ๊ตฌ์ฑ ์์๊ฐ ํํฌ์ ๊ตฌํ ์ธ๋ถ ์ฌํญ์ ๋ํด ์๊ณ ์์ด์ผ ํ๋ค๋ ๊ฒ์ ๋๋ค...
๋๋ ์ด๊ฒ์ด ๊ตฌํ ์ธ๋ถ ์ฌํญ์ด๋ผ๊ณ ๋งํ์ง ์์ ๊ฒ์ ๋๋ค. ๊ทธ๊ฒ์ ๋น์ ์ API์ ๋๋ค. ๊ฐ์ฒด๊ฐ ์ ๋ฌ๋๋ฉด ์ธ์ ๋ ์ง ๋ณ๊ฒฝ๋ ์ ์๋ค๊ณ ๊ฐ์ ํฉ๋๋ค.
์ค์ ๋ก ํญ์ ์ ์ ์ด๋ผ๋ฉด Hook ํฉํ ๋ฆฌ์ ๋ํ ์ธ์๋ก ๋ง๋ค ์ ์์ต๋๋ค. ๋ง์ฐฌ๊ฐ์ง๋ก createFetch(config)
๋ฐํ์ด useFetch()
. ์ต๊ณ ์์ค์ ๊ณต์ฅ์ ์ ํํฉ๋๋ค.
์กฐ๊ธ ์ด์ํ๊ฑด ์ดํดํฉ๋๋ค. ํ์ฌ ์์
์ค์ธ useSubscription
๋น์ทํ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ด๊ฒ์ ์ผ๋ฐ์ ์ธ ๋ฌธ์ ์ด๋ฏ๋ก useMemo
์ค์ ๋ก ํฉ๋ฒ์ ์ธ ๋ต๋ณ์์ ์๋ฏธํ ์ ์์ผ๋ฉฐ ์ฌ๋๋ค์ ์ด๋ฌํ ๊ฒฝ์ฐ์ ์ต์ํด์ ธ์ผ ํฉ๋๋ค.
์ค์ ๋ก โ ์ฐ๋ฆฌ๋ ์์ผ๋ก ์ด๊ฒ์ ๋ํด ๋ ๋ง์ด ์ดํด๋ณผ ๊ฒ์ ๋๋ค. ๊ทธ๋ฌ๋ ์ ์ฌ์ ์ผ๋ก ๋์ ์ธ ๊ฐ์ฒด๋ฅผ ์ ์ ๊ฐ์ฒด๋ก ์ทจ๊ธํด์๋ ์ ๋ฉ๋๋ค. ๊ทธ๋ฌ๋ฉด ์ฌ์ฉ์๊ฐ ๋ณ๊ฒฝํ ์ ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
@asylejmani ์๋จ ๊ฒ์๋ฌผ์์ ์์ฒญํ ๋๋ก ์ฌ์ฉ ์ฌ๋ก์ ๋ํ ์ธ๋ถ ์ ๋ณด๋ฅผ ์ ๊ณตํ์ง ์์์ต๋๋ค. ๋๊ตฐ๊ฐ๊ฐ ๊ทํ์ ์ง๋ฌธ์ ๋ํ ๋ต๋ณ์ ์ ๊ณตํ ์ ์๊ธฐ๋ฅผ ๊ธฐ๋ํ๋ ์ด์ ๋ ๋ฌด์์ ๋๊น?
๊ท์น์ ์์ ์ environment
๋ฐ dsn
๊ฐ ์๊ฐ์ด ์ง๋จ์ ๋ฐ๋ผ ๋ณ๊ฒฝ๋ ์ ์์ผ๋ฉฐ ๊ตฌ์ฑ ์์๊ฐ ์ด๋ฅผ ์ฒ๋ฆฌํด์ผ ํ๋ค๋ ๊ฒ์ ์๋ ค์ฃผ๋ ๊ฒ์
๋๋ค. ๋ฐ๋ผ์ ๊ตฌ์ฑ ์์๊ฐ ๋ฒ๊ทธ๊ฐ ์๊ฑฐ๋(ํด๋น ๊ฐ์ ๋ํ ๋ณ๊ฒฝ ์ฌํญ์ ์ฒ๋ฆฌํ์ง ์๊ธฐ ๋๋ฌธ์) ์ค์ํ์ง ์์ ๊ณ ์ ํ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค(์ด ๊ฒฝ์ฐ ์ด์ ๋ฅผ ์ค๋ช
ํ๋ ์ฃผ์์ ๋ฌด์ํ๋ ๋ฆฐํธ ๊ท์น์ ์ถ๊ฐํด์ผ ํจ).
๋ ๊ฒฝ์ฐ ๋ชจ๋ ๋น์ ์ด ๋ฌด์์ ๋ฌป๋์ง ๋ช ํํ์ง ์์ต๋๋ค. ๊ท์น์ ์ํฉ์ด ๋ณํ ์ ์๋ค๊ณ ๋ถํํ๋ฉฐ ๊ทธ ๋ณ๊ฒฝ์ ์ฒ๋ฆฌํ์ง ์์ต๋๋ค. ์์ ํ ์๊ฐ ์์ผ๋ฉด ์ฒ๋ฆฌ๊ฐ ํ์ํ์ง ์๋ค๊ณ ์๊ฐํ๋ ์ด์ ์ ๋ํด ์ค์ค๋ก ๋ตํ ์ ์์ต๋๋ค.
@gaearon ๋ ๋ช ํํ์ง
๋๋ ๋น ๋ฐฐ์ด์ด ๊ทธ๋ ๊ฒ ํ๋ ๊ฒ๋ณด๋ค ์ธ์์ ๋ฐ์์ง๋ง ๊ท์น์ ํญ์ ๋ฐฐ์ด์ ์ข ์์ฑ์ ํฌํจํ๋ผ๊ณ ๋งํฉ๋๋ค.
@asylejmani componentDidMount
์ ๊ฐ์ ํด๋์ค ๋ผ์ดํ ์ฌ์ดํด ๋ฉ์๋์์ ๊ฐ์ฅ ํฐ ๋ฌธ์ ๋ ์ฐ๋ฆฌ๊ฐ ๊ทธ๊ฒ์ ๊ฒฉ๋ฆฌ๋ ๋ฉ์๋๋ก ์๊ฐํ๋ ๊ฒฝํฅ์ด ์์ง๋ง ์ค์ ๋ก๋ ํ๋ฆ์ ์ผ๋ถ๋ผ๊ณ ์๊ฐํฉ๋๋ค.
componentDidMount
์์ ๋ฌด์ธ๊ฐ๋ฅผ ์ฐธ์กฐํ๋ ๊ฒฝ์ฐ componentDidUpdate
์์๋ ์ฒ๋ฆฌํด์ผ ํ ๊ฒ์
๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ๊ตฌ์ฑ ์์์ ๋ฒ๊ทธ๊ฐ ์๊ธธ ์ ์์ต๋๋ค.
์ด๊ฒ์ ๊ท์น์ด ์์ ํ๋ ค๋ ๊ฒ์ด๋ฏ๋ก ์๊ฐ์ด ์ง๋จ์ ๋ฐ๋ผ ๊ฐ์ ์ฒ๋ฆฌํด์ผ ํฉ๋๋ค.
1๋ฒ์ componentDidMount
/ useEffect
๋ณธ๋ฌธ์ ๋
ผ๋ฆฌ๋ฅผ ๋ฃ๋ ๊ณณ์
๋๋ค.
2๋ฒ์ componentDidUpdate
/ useEffect
deps์ ๋
ผ๋ฆฌ๋ฅผ ๋ฃ๋ ๊ณณ์
๋๋ค.
๊ท์น์ ํ๋ฆ์ ๋ ๋ฒ์งธ ๋ถ๋ถ์ ์ํํ์ง ์๊ณ ์๋ค๊ณ ๋ถํํฉ๋๋ค.
@gaearon ๋ ๋ช ํํ์ง
๋๋ ๋น ๋ฐฐ์ด์ด ๊ทธ๋ ๊ฒ ํ๋ ๊ฒ๋ณด๋ค ์ธ์์ ๋ฐ์์ง๋ง ๊ท์น์ ํญ์ ๋ฐฐ์ด์ ์ข ์์ฑ์ ํฌํจํ๋ผ๊ณ ๋งํฉ๋๋ค.
๋์ @asylejmani ๋ ์ฌ๊ธฐ์์ ๊ฐ์ ํ์ด์ง์ ์๋ค๊ณ ์๊ฐํ์ง๋ง @gaearon ์ด ๋งํ๋ ๊ฒ์ ์ค์ ๋ก ์ข
์์ฑ์ด ์๋ ๊ฒฝ์ฐ์๋ง ๋ง์ดํธ์ ๋ํ ํจ๊ณผ๋ฅผ ์คํํ๋ ๊ฒ์ด ์๋ชป๋ ๊ฒ์ผ ์ ์๋ค๋ ๊ฒ์
๋๋ค.
์ ๋นํ ๋ง์
๋๊น? ๋น ๋ฐฐ์ด์ ์ ๊ณตํ๋ ๊ฒ์ "๋ด๊ฐ ํ๋ ์ผ์ ์๊ณ ์์ต๋๋ค"๋ผ๊ณ ๋งํ๋ ๊ฒ๊ณผ ๋น์ทํ๋ค๊ณ ์๊ฐํ์ง๋ง ์ฌ์ ํ ๊ท์น์ ์ ์งํ๋ ค๋ ์ด์ ๋ฅผ ์ ์ ์์ต๋๋ค.
์์ง ์๋๋ฐ์ค๋ฅผ ์ ๊ณตํ์ง ๋ชปํด ์ฃ์กํฉ๋๋ค. ๋๋ Create React App ์์ ๋ก ๋ค๋ฅธ ๋ ๋ฐค์ ์์ํ๋๋ฐ ์๋๋ฐ์ค์์ eslint๋ฅผ ์คํํ๋ ๋ฐฉ๋ฒ์ ์ฐพ์ ์ ์์๊ณ , ๋จผ์ ์ ์ฅํ์ง ์๊ณ ๋ธ๋ผ์ฐ์ ๋ฅผ ๋ค์ ๋ก๋ํ ๋ ์๋๋ฐ์ค๋ฅผ ์์ด๋ฒ๋ ธ์ต๋๋ค(CodeSandbox ์์ ์ ์ฅ, ๋ด ์๋ชป).
๊ทธ ๋ค์ ๋๋ ์ ์๋ฆฌ์ ๋ค์ด์ผ ํ๊ณ , ๊ทธ ์ดํ๋ก ์๊ฐ์ด ์์์ต๋๋ค.
์ด์จ๋ , ๋๋ ๋น์ ์ด ๋งํ๋ ๊ฒ์ ์ดํดํ๊ณ ์ ์์ ์ธ ์๋๋ฆฌ์ค์์๋ ์ด๋ฌํ ์ข ์์ฑ์ ํฌํจํ๊ณ ๋ง์ดํธ์์๋ง ์คํํ๊ธฐ์ ์ถฉ๋ถํ๋ค๊ณ ๊ฐ์ ํ์ง ์๋ ๊ฒ์ด ๊ฐ์ฅ ์ข์ต๋๋ค.
์ด์ ๋ํ ์ ํจํ ์ฌ์ฉ ์ฌ๋ก๋ ์์ ์ ์์ง๋ง ์ค๋ช ํ๊ฑฐ๋ ์ข์ ์๋ฅผ ์ ์ํ๊ธฐ๊ฐ ์ฝ๊ฐ ์ด๋ ต๊ธฐ ๋๋ฌธ์ ํ์ํ ๋ ์ธ๋ผ์ธ ๊ท์น์ ๋นํ์ฑํํ๋ฉด์ ์ด๊ฒ ์ต๋๋ค.
@asylejmani ๋ https://github.com/facebook/react/issues/14920#issuecomment -466378650๊ณผ ์ ์ฌํ ์ฌ์ฉ ์ฌ๋ก์ ๋๋ค. ์ด ๊ฒฝ์ฐ ๊ท์น์ด ์๋๋ฆฌ์ค๋ฅผ ์ดํดํ ์ ์๋ค๊ณ ์๊ฐํ์ง ์์ผ๋ฏ๋ก ํด๋น ์ ํ์ ์ฝ๋์ ๋ํด ์๋์ผ๋ก ๋นํ์ฑํํด์ผ ํฉ๋๋ค. ๋ค๋ฅธ ๋ชจ๋ ๊ฒฝ์ฐ์๋ ๊ท์น์ด ์ ๋๋ก ์๋ํฉ๋๋ค.
์ด๊ฒ์ด ์๋ฏธ๊ฐ ์๋์ง ํ์คํ์ง ์์ง๋ง ๋์๊ฒ ๋งค์ฐ ์ผ๋ฐ์ ์ธ ์๋๋ฆฌ์ค๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
useEffect(() => {
if(!dataIsLoaded) { // flag from redux
loadMyData(); // redux action creator
}
}, []);
์ด ๋ ์ข ์์ฑ์ ๋ชจ๋ redux์์ ๊ฐ์ ธ์ต๋๋ค. ๋ฐ์ดํฐ(์ด ๊ฒฝ์ฐ)๋ ํ ๋ฒ๋ง ๋ก๋๋์ด์ผ ํ๋ฉฐ ์์ ์์ฑ์๋ ํญ์ ๋์ผํฉ๋๋ค.
์ด๊ฒ์ redux์๋ง ํด๋น๋๋ฉฐ eslint ๊ท์น์ ์ด๊ฒ์ ์ ์ ์์ผ๋ฏ๋ก ๊ฒฝ๊ณ ํด์ผ ํ๋ ์ด์ ๋ฅผ ์ ์ ์์ต๋๋ค. ๋น ๋ฐฐ์ด์ ์ ๊ณตํ๋ ๊ฒ์ด ๊ท์น์ ๋นํ์ฑํํด์ผ ํ๋์ง ์ฌ์ ํ ๊ถ๊ธํ์ญ๋๊น? ์ผ๋ถ๋ง ์ ๊ณตํ์ง๋ง ์ ๋ถ๋ ์๋ ๊ฒฝ์ฐ ๋๋ ์ ํ ์ ๊ณตํ์ง ์์ ๊ฒฝ์ฐ ๋๋ฝ๋ deps์ ๋ํด ๊ท์น์ด ์๋ ค์ฃผ๋ ๊ฒ์ด ๋ง์์ ๋ญ๋๋ค. ๋น ๋ฐฐ์ด์ ๋์ ๋ค๋ฅธ ๊ฒ์ ์๋ฏธํฉ๋๋ค. ํ์ง๋ง ์ ๋ง ๊ทธ๋ด ์๋ ์์ด์ :)
๋ชจ๋ ๋ ธ๋ ฅ์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค! ๊ทธ๋ฆฌ๊ณ ๊ฐ๋ฐ์๋ก์ ์ฐ๋ฆฌ์ ์ถ์ ๋ ์ข๊ฒ ๋ง๋ค๊ธฐ ์ํด :)
๋ด ์ฌ์ฉ ์ฌ๋ก๋ ํจ์ฌ ๊ฐ๋จํ๊ณ ๋ฌผ๋ก ๋ชจ๋ ์ข ์์ฑ์ ์ถ๊ฐํ ์ ์์ผ๋ฉฐ ์ฌ์ ํ ๋์ผํ๊ฒ ์๋ํ์ง๋ง ์ผ๋ถ ์ข ์์ฑ์ ์์ง๋ง ๋ค๋ฅธ ํญ๋ชฉ์ด ๋๋ฝ๋ ๊ฒฝ์ฐ ๊ท์น์ด "๊ฒฝ๊ณ "ํ๋ค๋ ์ธ์์ ๋ฐ์์ต๋๋ค.
@einarq ์ ์ฌ์ฉ ์ฌ๋ก๋ ๋ด๊ฐ ๋ช ๋ฒ ์ฌ์ฉํ ๊ฒ์ ๋๋ค. ์๋ฅผ ๋ค์ด "componentDidMount"์์ ๋ฐ์ดํฐ๊ฐ ์๋ ๊ฒฝ์ฐ(redux ๋๋ ๋ฌด์์ด๋ ) ๋ก๋ํฉ๋๋ค.
๋ํ ์ด๋ฌํ ๊ฒฝ์ฐ ์ธ๋ผ์ธ ๊ท์น์ ๋นํ์ฑํํ๋ ๊ฒ์ด ์ต์ ์ ์ ํ์ด๋ผ๋ ๋ฐ ๋์ํฉ๋๋ค. ๋น์ ์ ๋น์ ์ดํ๋ ์ผ์ ์ ํํ ์๊ณ ์์ต๋๋ค.
๋ด ๋ชจ๋ ํผ๋์ [] ๋ [์ผ๋ถ]์๋ค๊ณ ์๊ฐํ๊ณ ๋ฌผ๋ก ๋ฉ์ง ์์ ์ ๋ํด @gaearon ์๊ฒ ๊ฐ์ฌ๋๋ฆฝ๋๋ค :)
๋์ @asylejmani ๋ ์ฌ๊ธฐ์์ ๊ฐ์ ํ์ด์ง์ ์๋ค๊ณ ์๊ฐํ์ง๋ง @gaearon ์ด ๋งํ๋ ๊ฒ์ ์ค์ ๋ก ์ข ์์ฑ์ด ์๋ ๊ฒฝ์ฐ์๋ง ๋ง์ดํธ์ ๋ํ ํจ๊ณผ๋ฅผ ์คํํ๋ ๊ฒ์ด ์๋ชป๋ ๊ฒ์ผ ์ ์๋ค๋ ๊ฒ์ ๋๋ค. ์ ๋นํ ๋ง์ ๋๊น?
์. ๊ตฌ์ฑ ์์๊ฐ ์ํ์ ๋ํ ์
๋ฐ์ดํธ๋ฅผ ์ฒ๋ฆฌํ์ง ์๋ ๊ฒฝ์ฐ ์ผ๋ฐ์ ์ผ๋ก ๋ฒ๊ทธ๊ฐ ์์ต๋๋ค. useEffect
์ ๋์์ธ์ ๋น์ ์ด ๊ทธ๊ฒ์ ์ง๋ฉดํ๋๋ก ๊ฐ์ํฉ๋๋ค. ๋ฌผ๋ก ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์๋ ์์ง๋ง ๊ธฐ๋ณธ์ ์ผ๋ก ์ด๋ฌํ ๊ฒฝ์ฐ๋ฅผ ์ฒ๋ฆฌํ๋๋ก ์ ๋ํ๋ ๊ฒ์
๋๋ค. ์ด ์๊ฒฌ์ ์ ์ค๋ช
๋์ด ์์ต๋๋ค: https://github.com/facebook/react/issues/14920#issuecomment -470913287.
์ด ๋ ์ข ์์ฑ์ ๋ชจ๋ redux์์ ๊ฐ์ ธ์ต๋๋ค. ๋ฐ์ดํฐ(์ด ๊ฒฝ์ฐ)๋ ํ ๋ฒ๋ง ๋ก๋๋์ด์ผ ํ๋ฉฐ ์์ ์์ฑ์๋ ํญ์ ๋์ผํฉ๋๋ค.
๋์ผํ ๊ฒฝ์ฐ ์ข ์์ฑ์ ํฌํจํด๋ ๋ฌธ์ ๊ฐ ๋์ง ์์ต๋๋ค. ๋๋ ๊ทธ๊ฒ์ ๊ฐ์กฐํ๊ณ ์ถ์ต๋๋ค โ ๋น์ ์ ์์กด์ฑ์ด ๊ฒฐ์ฝ ๋ณํ์ง ์๋๋ค๊ณ ํ์ ํ๋ค๋ฉด ๊ทธ๊ฒ๋ค์ ๋์ดํ๋ ๋ฐ ์๋ฌด๋ฐ ํด๊ฐ ์์ต๋๋ค . ๊ทธ๋ฌ๋ ๋์ค์ ๋ณ๊ฒฝ๋๋ ๊ฒฝ์ฐ(์: ์์ ๊ตฌ์ฑ ์์๊ฐ ์ํ์ ๋ฐ๋ผ ๋ค๋ฅธ ๊ธฐ๋ฅ์ ์ ๋ฌํ๋ ๊ฒฝ์ฐ) ๊ตฌ์ฑ ์์๋ ์ด๋ฅผ ์ฌ๋ฐ๋ฅด๊ฒ ์ฒ๋ฆฌํฉ๋๋ค.
๋น ๋ฐฐ์ด์ ์ ๊ณตํ๋ ๊ฒ์ด ๊ท์น์ ๋นํ์ฑํํด์ผ ํ๋์ง ์ฌ์ ํ ๊ถ๊ธํ์ญ๋๊น?
์๋์. ๋น ๋ฐฐ์ด์ ์ ๊ณตํ ๋ค์ ์ผ๋ถ props ๋๋ state๊ฐ ์ค๋๋ ์ด์ ๋ฅผ ๊ถ๊ธํดํ๋ ๊ฒ์ ๋ง ๊ทธ๋๋ก ๊ฐ์ฅ ํํ ์ค์์ ๋๋ค.
>
์๋ฏธ๊ฐ ํฝ๋๋ค. ๊ฐ์ฌํฉ๋๋ค.
2019๋ 3์ 8์ผ 15:27์ Dan Abramov [email protected]์ด ๋ค์๊ณผ ๊ฐ์ด ์ผ์ต๋๋ค.
๋์ @asylejmani ๋ ์ฌ๊ธฐ์์ ๊ฐ์ ํ์ด์ง์ ์๋ค๊ณ ์๊ฐํ์ง๋ง @gaearon ์ด ๋งํ๋ ๊ฒ์ ์ค์ ๋ก ์ข ์์ฑ์ด ์๋ ๊ฒฝ์ฐ์๋ง ๋ง์ดํธ์ ๋ํ ํจ๊ณผ๋ฅผ ์คํํ๋ ๊ฒ์ด ์๋ชป๋ ๊ฒ์ผ ์ ์๋ค๋ ๊ฒ์ ๋๋ค. ์ ๋นํ ๋ง์ ๋๊น?
์. ๊ตฌ์ฑ ์์๊ฐ ์ํ์ ๋ํ ์ ๋ฐ์ดํธ๋ฅผ ์ฒ๋ฆฌํ์ง ์๋ ๊ฒฝ์ฐ ์ผ๋ฐ์ ์ผ๋ก ๋ฒ๊ทธ๊ฐ ์์ต๋๋ค. useEffect์ ๋์์ธ์ ๋น์ ์ด ๊ทธ๊ฒ์ ์ง๋ฉดํ๋๋ก ๊ฐ์ํฉ๋๋ค. ๋ฌผ๋ก ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์๋ ์์ง๋ง ๊ธฐ๋ณธ์ ์ผ๋ก ์ด๋ฌํ ๊ฒฝ์ฐ๋ฅผ ์ฒ๋ฆฌํ๋๋ก ์ ๋ํ๋ ๊ฒ์ ๋๋ค. ์ด ์ฃผ์์ ๊ทธ๊ฒ์ ์ ์ค๋ช ํฉ๋๋ค: #14920 (comment).
์ด ๋ ์ข ์์ฑ์ ๋ชจ๋ redux์์ ๊ฐ์ ธ์ต๋๋ค. ๋ฐ์ดํฐ(์ด ๊ฒฝ์ฐ)๋ ํ ๋ฒ๋ง ๋ก๋๋์ด์ผ ํ๋ฉฐ ์์ ์์ฑ์๋ ํญ์ ๋์ผํฉ๋๋ค.
๋์ผํ ๊ฒฝ์ฐ ์ข ์์ฑ์ ํฌํจํด๋ ๋ฌธ์ ๊ฐ ๋์ง ์์ต๋๋ค. ๋๋ ๊ทธ๊ฒ์ ๊ฐ์กฐํ๊ณ ์ถ์ต๋๋ค โ ๋น์ ์ ์์กด์ฑ์ด ๊ฒฐ์ฝ ๋ณํ์ง ์๋๋ค๊ณ ํ์ ํ๋ค๋ฉด ๊ทธ๊ฒ๋ค์ ๋์ดํ๋ ๋ฐ ์๋ฌด๋ฐ ํด๊ฐ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๋์ค์ ๋ณ๊ฒฝ๋๋ ๊ฒฝ์ฐ(์: ์์ ๊ตฌ์ฑ ์์๊ฐ ์ํ์ ๋ฐ๋ผ ๋ค๋ฅธ ๊ธฐ๋ฅ์ ์ ๋ฌํ๋ ๊ฒฝ์ฐ) ๊ตฌ์ฑ ์์๋ ์ด๋ฅผ ์ฌ๋ฐ๋ฅด๊ฒ ์ฒ๋ฆฌํฉ๋๋ค.
๋น ๋ฐฐ์ด์ ์ ๊ณตํ๋ ๊ฒ์ด ๊ท์น์ ๋นํ์ฑํํด์ผ ํ๋์ง ์ฌ์ ํ ๊ถ๊ธํ์ญ๋๊น?
์๋์. ๋น ๋ฐฐ์ด์ ์ ๊ณตํ ๋ค์ ์ผ๋ถ props ๋๋ state๊ฐ ์ค๋๋ ์ด์ ๋ฅผ ๊ถ๊ธํดํ๋ ๊ฒ์ ๋ง ๊ทธ๋๋ก ๊ฐ์ฅ ํํ ์ค์์ ๋๋ค.
โ
๋น์ ์ด ์ธ๊ธ๋์๊ธฐ ๋๋ฌธ์ ์ด๊ฒ์ ๋ฐ๋ ๊ฒ์ ๋๋ค.
์ด ์ด๋ฉ์ผ์ ์ง์ ๋ต์ฅํ๊ฑฐ๋ GitHub์์ ๋ณด๊ฑฐ๋ ์ค๋ ๋๋ฅผ ์์๊ฑฐํ์ธ์.
@ํผ๊ณคํ
๊ทธ๋ฌ๋ฉด ์ค์ ์ ๋ฐ์ดํธ๊ฐ ์ปค๋ฐ๋๊ธฐ ์ ์ ๋ถ์์ฉ์ด ๋ฐ์ํ์ฌ ์ํ๋ ๊ฒ๋ณด๋ค ๋ ์์ฃผ ๋ถ์์ฉ์ด ํธ๋ฆฌ๊ฑฐ๋ ์ ์์ต๋๋ค.
์ด๊ฒ ๋ฌด์จ ๋ป์ธ์ง ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ์๋ฅผ ๋ค์ด ์ค ์ ์์ต๋๊น?
์ฐ๋ฆฌ๋ ์ค๋ @threepointone ์ผ๋ก
useEffect
์ข
์์ฑ์ด ๊ท์น์ ํฉ๋ฒ์ ์ธ ์๋๋ฆฌ์ค๊ฐ ์์ผ๋ฏ๋ก ๋ ์ด์ "์ธ๋ถ" dep๋ฅผ useEffect
์ถ๊ฐํ๋ ๊ฒ์ ๋ฐฉ์งํ์ง ์์ต๋๋ค.
Linter๋ ์ง๊ธ ์์ ํ ๊ฒฝ์ฐ์ ๋ํด ๊ฒฝ๊ณ ํ์ง ์์ง๋ง ๋ค๋ฅธ ๋ชจ๋ ๊ฒฝ์ฐ์๋ ๋ ๋์ ์ ์์ ์ ๊ณตํฉ๋๋ค(์: ํจ๊ณผ ๋ด์์ ํจ์๋ฅผ ์ด๋ํ๊ฑฐ๋ useCallback
๋ํ).
์ด๊ฒ์ ๋ ์ด์ ๋ฆฐํธ ์๋ฐ์ ์์ฑํ์ง ์์ง๋ง props์ ๋ํ ์๋ต์ผ๋ก ์ํ๋ฅผ ์ฌ์ค์ ํ๋ ๊ด์ฉ์ ๋ฐฉ๋ฒ์ ๋ค๋ฆ ๋๋ค . ์ด ์๋ฃจ์ ์๋ ์ผ๊ด์ฑ ์๋ ๋ ๋๋ง์ด ์ถ๊ฐ๋ก ํฌํจ๋๋ฏ๋ก ๋ฐ๋์งํ์ง ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค.
ํํฌ๋ ๊ฐ๋ฅํ ํ ์ ํํจ์ ์ถ๊ตฌํฉ๋๋ค. ๋น์ ์ด (๊ฒฝ์ฐ์ ๋ฐ๋ผ์๋ ์๋ต ํ ์ ์์) deps๋ฅผ ์ง์ ํ๋ฉด, ์ฐ๋ฆฌ๋ ๊ฐํ๊ฒ ๋น์ ์ด ๋ณ๊ฒฝ๋์ง ์์ต๋๋ค ์๊ฐ๋ ์ฌ๋์ ํฌํจํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ์, ์ด useDebounce
์์์๋ ์ง์ฐ์ด ๋ณ๊ฒฝ ๋์ง ์์ ๊ฒ์
๋๋ค. ํ์ง๋ง ๋ฒ๊ทธ๊ฐ ๋ฐ์ํ๋ฉด ์ฌ์ ํ ๋ฒ๊ทธ์ด์ง๋ง Hook์ ์ด๋ฅผ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค. ์ด๊ฒ์ ๋ค๋ฅธ ์๋๋ฆฌ์ค์์๋ ๋ํ๋ฉ๋๋ค. (์: Hooks๋ ๋ชจ๋ ๊ฐ์ด ๋์ ์ผ๋ก ์ฒ๋ฆฌ๋๊ธฐ ๋๋ฌธ์ ํซ ๋ฆฌ๋ก๋ฉ๊ณผ ํจ์ฌ ๋ ํธํ๋ฉ๋๋ค.)
ํน์ ๊ฐ์ด ์ ์ ์ด๋ผ๊ณ ์ ๋์ ์ผ๋ก ์ฃผ์ฅํ๋ค๋ฉด ๊ฐ์ ํ ์ ์์ต๋๋ค.
๊ฐ์ฅ ์์ ํ ๋ฐฉ๋ฒ์ API์์ ๋ช
์์ ์ผ๋ก ์ํํ๋ ๊ฒ์
๋๋ค.
const useFetch = createFetch({ /* config object */});
const useDebounce = createDebounce(500);
const FormInput = createInput({ rules: [emailValidator, phoneValidator] });
๊ทธ๋ฐ ๋ค์ render ์์ ๋ฃ์ง ์๋ ํ ๋ถ๋ช
ํ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค. (์ด๊ฒ์ Hook์ ๊ด์ฉ์ ์ฌ์ฉ๋ฒ์ด ์๋๋๋ค.) ํ์ง๋ง <Slider min={50} />
can never change ๋ผ๋ ๋ง์ ์ค์ ๋ก ์ ํจํ์ง ์์ต๋๋ค โ ๋๊ตฐ๊ฐ ๊ทธ๊ฒ์ <Slider min={state ? 50 : 100} />
์ฝ๊ฒ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค. ์ค์ ๋ก ๋๊ตฐ๊ฐ๋ ๋ค์๊ณผ ๊ฐ์ด ํ ์ ์์ต๋๋ค.
let slider
if (isCelsius) {
slider = <Slider min={0} max={100} />
} else {
slider = <Slider min={32} max={212} />
}
๋๊ตฐ๊ฐ isCelsius
์ํ๋ฅผ ์ ํํ๋ฉด min
๋ณ๊ฒฝ๋์ง ์๋๋ค๊ณ ๊ฐ์ ํ๋ ๊ตฌ์ฑ ์์๊ฐ ์
๋ฐ์ดํธ๋์ง ์์ต๋๋ค. ์ด ๊ฒฝ์ฐ Slider
๊ฐ ๋์ผํ์ง ์ฌ๋ถ๋ ๋ถ๋ช
ํ์ง ์์ต๋๋ค(๊ทธ๋ฌ๋ ํธ๋ฆฌ์์ ๋์ผํ ์์น์ ์๊ธฐ ๋๋ฌธ์ผ ๊ฒ์
๋๋ค). ๋ฐ๋ผ์ ์ด๊ฒ์ ์ฝ๋๋ฅผ ๋ณ๊ฒฝํ๋ ์ธก๋ฉด์์ ์ค์ํ ๋ฐํ์
๋๋ค. React์ ์ฃผ์ ํฌ์ธํธ๋ ์
๋ฐ์ดํธ๊ฐ ์ด๊ธฐ ์ํ์ฒ๋ผ ๋ ๋๋ง๋๋ค๋ ๊ฒ์
๋๋ค(๋ณดํต ์ด๋ ๊ฒ์ด ์ด๋ ์ํ์ธ์ง ์ ์ ์์). prop ๊ฐ B๋ฅผ ๋ ๋๋งํ๋ prop ๊ฐ A์์ B๋ก ์ด๋ํ๋ ์๊ด์์ด ๋์ผํ๊ฒ ๋ณด์ด๊ณ ์๋ํด์ผ ํฉ๋๋ค.
์ด๊ฒ์ ๋ฐ๋์งํ์ง ์์ง๋ง ๊ฒฝ์ฐ์ ๋ฐ๋ผ ์ ์ฉ ๋ฉ์ปค๋์ฆ์ ๊ฐ์ด ๋ณ๊ฒฝ๋ ๋ ๊ฒฝ๊ณ ํ๋(๊ทธ๋ฌ๋ ์ฒซ ๋ฒ์งธ ๊ฐ์ ์ ๊ณตํ๋) ํํฌ์ผ ์ ์์ต๋๋ค. ์ ์ด๋ ๊ทธ๋๋ ์ฃผ๋ชฉ๋ฐ์ ๊ฐ๋ฅ์ฑ์ด ๋ ํฝ๋๋ค.
function useMyHook(a) {
const initialA = usePossiblyStaleValue(a);
// ...
}
function usePossiblyStaleValue(value) {
const ref = useRef(value);
if (process.env.NODE_ENV !== 'production') {
if (ref.current !== value) { // Or your custom comparison logic
console.error(
'Unlike normally in React, it is not supported ' +
'to pass dynamic values to useMyHook(). Sorry!'
);
}
}
return ref.current;
}
์
๋ฐ์ดํธ๋ฅผ ์ฒ๋ฆฌ ํ ์ ์๋ ํฉ๋ฒ์ ์ธ ๊ฒฝ์ฐ๋ ์์ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด jQuery ํ๋ฌ๊ทธ์ธ์ด๋ DOM API์ ๊ฐ์ด ํ์ ์์ค API๊ฐ ์ง์ํ์ง ์๋ ๊ฒฝ์ฐ์ ๊ฐ์ต๋๋ค. ์ด ๊ฒฝ์ฐ ๊ตฌ์ฑ ์์์ ์๋น์๊ฐ ์ดํดํ ์ ์๋๋ก ๊ฒฝ๊ณ ๊ฐ ์ฌ์ ํ ์ ์ ํฉ๋๋ค. ๋๋ ํธํ๋์ง ์๋ ์
๋ฐ์ดํธ์์ key
๋ฅผ ์ฌ์ค์ ํ๋ ๋ํผ ๊ตฌ์ฑ ์์๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค. ์ฌ๋ผ์ด๋๋ ์ฒดํฌ๋ฐ์ค์ ๊ฐ์ ๋ฆฌํ ๊ตฌ์ฑ์์์ ๋ ์ ํฉํ ๊ฒ์
๋๋ค.
์ฐ์ , ๊ทธ๊ฒ์ด ์ผ์ ํ๊ณ ์ต์์ ๋ฒ์๋ก ํธ์ด์คํธ๋๋ฉด ๋ฆฐํฐ๋ ๋ถํํ์ง ์์ ๊ฒ์ ๋๋ค. ๊ทธ๋ฌ๋ ๊ทธ๊ฒ์ ์ํ์ด๋ ์ปจํ ์คํธ์์ ์ค๋ ๊ฒ์๋ ๋์์ด ๋์ง ์์ต๋๋ค.
๊ทธ๊ฒ์ด ์ง์ ์ผ๋ก ์ผ์ ํ๋ค๋ฉด deps๋ก ์ง์ ํด๋ ๋ฌธ์ ๊ฐ ๋์ง ์์ต๋๋ค. ์ฌ์ฉ์ ์ ์ Hook ๋ด๋ถ์ setState
ํจ์๊ฐ ๊ตฌ์ฑ ์์๋ก ๋ฐํ๋ ๋ค์ ํจ๊ณผ์์ ํธ์ถํ๋ ๊ฒฝ์ฐ์ ๊ฐ์ด. Lint ๊ท์น์ ์ด์ ๊ฐ์ ๊ฐ์ ์ฐธ์กฐ๋ฅผ ์ดํดํ ๋งํผ ๋๋ํ์ง ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๋ค๋ฅธ ํํธ์ผ๋ก ๋๊ตฌ๋ ์ง ๋ฐํํ๊ธฐ ์ ์ ๋์ค์ ํด๋น ์ฝ๋ฐฑ์ ๋ํํ ์ ์์ผ๋ฉฐ ๊ทธ ์์ ์๋ ๋ค๋ฅธ prop ๋๋ state๋ฅผ ์ฐธ์กฐํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ฉด ์ผ์ ํ์ง ์์ต๋๋ค! ๊ทธ๋ฆฌ๊ณ ์ด๋ฌํ ๋ณ๊ฒฝ ์ฌํญ์ ์ฒ๋ฆฌํ์ง ๋ชปํ๋ฉด ๋ถ์พํ prop/state ๋ฒ๊ทธ๊ฐ ๋ฐ์ํฉ๋๋ค. ๋ฐ๋ผ์ ์ง์ ํ๋ ๊ฒ์ด ๋ ๋์ ๊ธฐ๋ณธ๊ฐ์
๋๋ค.
๊ทธ๋ฌ๋ ํจ์ ๊ฐ์ด ๋ฐ๋์ ์ผ์ ํ๋ค๋ ๊ฒ์ ์๋ชป๋ ์๊ฐ์
๋๋ค. ์์ฒด์ ์ธ ๋ฒ๊ทธ ๋ฒ์ ๋ฅผ ์์ฑํ์ง๋ง ๋ฉ์๋ ๋ฐ์ธ๋ฉ์ผ๋ก ์ธํด ํด๋์ค์์ ๋ ์์ฃผ ์ผ์ ๋ด๋ถ ๋ก ์ด๋ํ๊ฑฐ๋ useCallback
๋ํ)
์ด๊ฒ์ ๋ฐ๋ ์คํํธ๋ผ์๋ ๋ฌดํ ๋ฃจํ๊ฐ ๋ฐ์ํ๋ ๋ฌธ์ ๊ฐ ์์ต๋๋ค(ํจ์ ๊ฐ์ ํญ์ ๋ณ๊ฒฝ๋จ). ๊ฐ๋ฅํ ๊ฒฝ์ฐ(๋์ผํ ๊ตฌ์ฑ ์์์์) ์ด์ Lint ๊ท์น์์ ์ด๋ฅผ ํฌ์ฐฉํ๊ณ ์์ ์ฌํญ์ ์ ์ํฉ๋๋ค. ๊ทธ๋ฌ๋ ๋ช ๋จ๊ณ ์๋๋ก ๋ฌด์ธ๊ฐ๋ฅผ ํต๊ณผํ๋ฉด ๊น๋ค๋กญ์ต๋๋ค.
์ฌ์ ํ useCallback
๋ก ๊ฐ์ธ์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์ต๋๋ค. ๊ธฐ์ ์ ์ผ๋ก ํจ์๊ฐ ๋ณ๊ฒฝ๋๋ ๊ฒ์ ์ ํจํ๋ฉฐ ๋ฒ๊ทธ์ ์ํ ์์ด ์ด ๊ฒฝ์ฐ๋ฅผ ๋ฌด์ํ ์ ์์ต๋๋ค. onChange={shouldHandle ? handleChange : null}
๋๋ ๊ฐ์ ์์น์์ foo ? <Page fetch={fetchComments /> : <Page fetch={fetchArticles />
๋ ๋๋ง ๋ฑ. ๋๋ ์์ ๊ตฌ์ฑ ์์ ์ํ๋ฅผ ๋ซ๋ fetchComments
์์ต๋๋ค. ๋ณ๊ฒฝ ๋ ์ ์์ต๋๋ค. ํด๋์ค๋ฅผ ์ฌ์ฉํ๋ฉด ๋์์ด ์๋์ผ๋ก ๋ณ๊ฒฝ๋์ง๋ง ํจ์ ์ฐธ์กฐ๋ ๋์ผํ๊ฒ ์ ์ง๋ฉ๋๋ค. ๋ฐ๋ผ์ ์๋
๋ ํด๋น ์
๋ฐ์ดํธ๋ฅผ ๋์น ๊ฒ์
๋๋ค. ์๋
์๊ฒ ๋ ๋ง์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ๊ฒ ์ธ์๋ ์ต์
์ด ์์ต๋๋ค. ํจ์ ๊ตฌ์ฑ ์์์ useCallback
๋ฅผ ์ฌ์ฉํ๋ฉด ํจ์ ID ์์ฒด๊ฐ ๋ณ๊ฒฝ๋์ง๋ง ํ์ํ ๊ฒฝ์ฐ์๋ง ๋ณ๊ฒฝ๋ฉ๋๋ค. ๋ฐ๋ผ์ ์ด๋ ์ ์ฉํ ์์ฑ์ด๋ฉฐ ํผํด์ผ ํ ์ฅ์ ๋ฌผ์ด ์๋๋๋ค.
๋ฌดํ ๋น๋๊ธฐ ๋ฃจํ๋ฅผ ๊ฐ์งํ๊ธฐ ์ํ ๋ ๋์ ์๋ฃจ์ ์ ์ถ๊ฐํด์ผ ํฉ๋๋ค. ๊ฐ์ฅ ํผ๋์ค๋ฌ์ด ์ธก๋ฉด์ ์ํํด์ผ ํฉ๋๋ค. ํฅํ ์ด์ ๋ํ ๊ฐ์ง ๊ธฐ๋ฅ์ ์ถ๊ฐํ ์ ์์ต๋๋ค. ๋ค์๊ณผ ๊ฐ์ด ์ง์ ์์ฑํ ์๋ ์์ต๋๋ค.
useWarnAboutTooFrequentChanges([deps]);
์ด๊ฒ์ ์ด์์ ์ด์ง ์์ผ๋ฉฐ ์ฐ๋ฆฌ๋ ์ด๊ฒ์ ๋ ์ฐ์ํ๊ฒ ์ฒ๋ฆฌํ๋ ๊ฒ์ ๋ํด ์๊ฐํ ํ์๊ฐ ์์ต๋๋ค. ๋ด๊ฐ ์ข์ํ๋ ๊ฒฝ์ฐ ๋์ ์ด ๊ฝค ๋ถ์พํ์
๋๋ค. ๊ท์น์ ์๋ฐํ์ง ์๊ณ ์์ ํ๋ ๊ฒ์ rules
์ ์ ์ผ๋ก ๋ง๋๋ ๊ฒ์
๋๋ค(์: API๋ฅผ createTextInput(rules)
๋ก ๋ณ๊ฒฝํ๊ณ register
๋ฐ unregister
์ useCallback
. ๋ ์ข์ ๋ฐฉ๋ฒ์ register
๋ฐ unregister
๋ฅผ ์ ๊ฑฐํ๊ณ dispatch
๋ง ๋ฃ๋ ๋ณ๋์ ์ปจํ
์คํธ๋ก ๋ฐ๊พธ๋ ๊ฒ์
๋๋ค. ๊ทธ๋ฐ ๋ค์ ์ฝ๋ ๊ฒ๊ณผ ๋ค๋ฅธ ๊ธฐ๋ฅ ID๋ฅผ ๊ฐ์ง ์์ ๊ฒ์์ ๋ณด์ฅํ ์ ์์ต๋๋ค.
๊ณต๊ธ์๊ฐ ์ ๊ตฌ์ฑ ์์๊ฐ ๋ฑ๋ก๋์ง ์์์ง๋ง ์์ฒด ๋ถ๋ชจ๊ฐ ์
๋ฐ์ดํธ๋ ๊ฒฝ์ฐ ๋ฐ๋ณต์ ์ผ๋ก ์ฌํ ๋ง์ ๊ณ์ฐ์ ์ํํ๊ธฐ ๋๋ฌธ์ ์ด์จ๋ ์ปจํ
์คํธ ๊ฐ์ useMemo
๋ฅผ ์ถ๊ฐํ๊ณ ์ถ์ ๊ฒ์
๋๋ค. ๋ฐ๋ผ์ ์ด๋ฌํ ์ข
๋ฅ์ ๋ฌธ์ ๋ ๊ทธ๋ ์ง ์์ผ๋ฉด ๋ ๋์ ๋์ง ์์ ์ ์๋ ๋ฌธ์ ๋ฅผ ๋ฃ์ต๋๋ค. ๋๋ ์ด๊ฒ์ด ์ผ์ด๋ ๋ ์ฐ๋ฆฌ๊ฐ ๋์ฑ ๋๋๋ฌ์ง๊ฒ ๋ง๋ค ํ์๊ฐ ์๋ค๋ ๋ฐ ๋์ํ์ง๋ง.
ํจ์ ์ข ์์ฑ์ ์์ ํ ๋ฌด์ํ๋ฉด ํจ์ ๊ตฌ์ฑ ์์์ Hooks์์ ๋ ๋์ ๋ฒ๊ทธ๋ก ์ด์ด์ง๋๋ค. ๊ทธ๋ ๊ฒ ํ๋ฉด ๊ณ์ ์ค๋๋ props์ state๊ฐ ํ์๋๊ธฐ ๋๋ฌธ์ ๋๋ค. ๊ทธ๋ฌ๋ ํ ์ ์์ ๋ ํ์ง ๋ง์ญ์์ค.
์ด ์์ ๊ฐ ๋ณธ์ง์ ์ผ๋ก ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ๋ํ ํจ๊ณผ๋ฅผ ์ฌ์ฉํ๋ ์ด์ ๊ฐ ์ด์ํฉ๋๋ค. ์ด๋ฒคํธ ํธ๋ค๋ฌ์์ ๋์ผํ "๋ก๊ทธ"(์์ ์ ์ถ์ผ ์ ์๋ค๊ณ ๊ฐ์ )๋ฅผ ์ํํ๋ ๊ฒ์ด ๋ ์ ํฉํด ๋ณด์ ๋๋ค. ๊ตฌ์ฑ ์์๊ฐ ๋ง์ดํธ ํด์ ๋ ๋ ์ด๋ค ์ผ์ด ๋ฐ์ํ๋์ง ์๊ฐํ๋ฉด ํนํ ๊ทธ๋ ์ต๋๋ค. ํจ๊ณผ๊ฐ ์์ฝ๋ ์งํ ๋ง์ดํธ๋ฅผ ํด์ ํ๋ฉด ์ด๋ป๊ฒ ๋ฉ๋๊น? ์์ ์ ์ถ๊ณผ ๊ฐ์ ์ผ์ ์ด ๊ฒฝ์ฐ์ "๋ฐ์ํ์ง ์์์ผ" ํฉ๋๋ค. ๊ทธ๋์ ํจ๊ณผ๊ฐ ์๋ชป๋ ์ ํ์ผ ์ ์๋ ๊ฒ ๊ฐ์ต๋๋ค.
์ฆ, fullName
๋ฅผ setSubmittedData({firstName, lastName})
๋์ [submittedData]
๋ก ๋ง๋ค๊ณ firstName
์ฝ์ ์ ์๋ ์ข
์์ฑ์ ํตํด ์๋ํ ์์
์ ๊ณ์ ์ํํ ์ ์์ต๋๋ค lastName
.
jQuery ํ๋ฌ๊ทธ์ธ ๋๋ ์์ DOM API์ ๊ฐ์ ํ์ ํญ๋ชฉ๊ณผ ํตํฉํ ๋ ์ฝ๊ฐ์ ๋ถํธํจ์ด ์์๋ ์ ์์ต๋๋ค. ์ฆ, ํด๋น ์์ ์์ ํจ๊ณผ ๋ฅผ ์ข ๋ ํตํฉํ ์ ์์ ๊ฒ์ผ๋ก ๊ธฐ๋ํฉ๋๋ค.
์๋ฌด๋ ์์ง ์์์ผ๋ฉด ์ข๊ฒ ์ด! ๋ด๊ฐ ํ ๊ฒฝ์ฐ ๋๋ ๋ญ๊ฐ ๋ช ํํ์ง ์์ ๊ฒฝ์ฐ ์๋ ค์ฃผ์ญ์์ค. ์ฐ๋ฆฌ๋ ๊ณง ์ด๊ฒ์ ๊ตํ์ ์ผ๋ถ ๋ฌธ์๋ก ๋ฐ๊พธ๋ ค๊ณ ๋ ธ๋ ฅํ ๊ฒ์ ๋๋ค.
@gaearon , ์๊ฐ์ ๋ด์ด ๋ฌธ์ ๋ฅผ (@trevorgithub์ #14920(๋๊ธ))์ ๋์ณค์ต๋๋ค . (๋ง์ ๋ถ๋ค์ด ํผ๋๋ฐฑ์ ๋ง์ด ์ฃผ์ ์ ์ ๋ง ๊ฐ์ฌํฉ๋๋ค. ์ ์๋ ๋๊ธ์ด ์ด์ ๋๊ธ ์ค๊ฐ์ ์จ๊ฒจ์ง ํญ๋ชฉ ์น์ ์์ ์ฌ๋ผ์ง ๊ฒ ๊ฐ์ต๋๋ค.)
๋ด ์ํ์ด 'ํ์/๋ ๊ฑฐ์ ์ฝ๋์ ํตํฉ'์ ์ํ๋ค๊ณ ๊ฐ์ ํ์ง๋ง ๋ค๋ฅธ ๋ฒ์ฃผ๋ ๋ง์ฐฌ๊ฐ์ง์ ๋๊น?
'Imperative/Legacy Code์ ํตํฉ' ๋ฌธ์ ์ ๊ฒฝ์ฐ ํ ์ ์๋ ์ผ์ด ๋ง์ง ์์ ์ ์์ต๋๋ค. ๊ทธ๋ฌํ ๊ฒฝ์ฐ ์ด๋ป๊ฒ ์ด ๊ฒฝ๊ณ ๋ฅผ ๋ฌด์ํ๊ฒ ์ต๋๊น? ๋๋ ์ถ์ธกํ๋ค:
// eslint-disable-line react-hooks/exhaustive-deps
์ฃ์กํฉ๋๋ค.
props๋ฅผ ํตํด ์ผ๋ถ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ง๋ง ๋ช ์์ ์ธ ๋ณ๊ฒฝ์ด ์์ ๋๊น์ง ํด๋น props๋ฅผ ์ฌ์ฉํ๊ณ ์ถ์ง ์๋ค๋ฉด ํ์๋ ์ํ๋ฅผ ๊ฐ๋ ๊ฒ์ด ์ฌ๋ฐ๋ฅธ ๋ชจ๋ธ๋ง ๋ฐฉ๋ฒ์ฒ๋ผ ๋ค๋ฆฝ๋๋ค.
"๋ค๋ฅธ prop์ด ๋์ฌ ๋๊น์ง prop์ ๋ํ ๋ณ๊ฒฝ์ ๋ฌด์ํ๊ณ ์ถ์ต๋๋ค"๋ผ๊ณ ์๊ฐํ๊ณ ์์ต๋๋ค. ๊ทธ๋ฌ๋ "๋ด ๊ตฌ์ฑ ์์์๋ ์ํ์์ ๊ฐ์ ธ์ค๊ธฐ ๊ธฐ๋ฅ์ด ์์ต๋๋ค. ๋ค๋ฅธ ์ํ์ด ๋ณ๊ฒฝ๋๋ฉด ์ํ์์ ์ ๋ฐ์ดํธ๋ฉ๋๋ค.โ
์ผ๋ฐ์ ์ผ๋ก ํ์๋ ์ํ๋ ๊ถ์ฅ๋์ง ์์ง๋ง ์ฌ๊ธฐ์๋ ์ํ๋ ๊ฒ์ฒ๋ผ ๋ณด์ ๋๋ค. ์ด๋ฅผ ๊ตฌํํ๋ ๊ฐ์ฅ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
const [currentGetData, setCurrentGetData] = useState(getData);
const [prevRefreshRequest, setPrevRefreshRequest] = useState(refreshRequest);
if (prevRefreshRequest !== refreshRequest) {
setPrevRefreshRequest(refreshRequest);
setCurrentGetData(getData);
}
useEffect(() => {
currentGetData(someId);
}, [currentGetData, someId]);
๋ํ ๋ ํ์๊ฐ ๊ฑฐ๋ผ๊ณ useCallback
์ฝ getData
๋น์ ์ด ์๋๋ก ์ ๋ฌํ๋ ๊ฒ์ด๋ค.
์ผ๋ฐ์ ์ผ๋ก ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ์ํด ๋น๋๊ธฐ ํจ์๋ฅผ ์ ๋ฌํ๋ ํจํด์ ๋์๊ฒ ๊ทธ๋์ง ๊ฒ์ฒ๋ผ ๋ณด์ ๋๋ค. ๊ทํ์ ๊ฒฝ์ฐ Redux๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ํฉ๋ฆฌ์ ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ๊ทธ๋ฌ๋ ๋ถ๋ชจ ๊ตฌ์ฑ ์์์ ๋น๋๊ธฐ ํจ์๊ฐ ์ ์๋ ๊ฒฝ์ฐ ๊ฒฝ์ ์กฐ๊ฑด์ด ์์ ์ ์์ผ๋ฏ๋ก ์์ฌ์ค๋ฝ์ต๋๋ค. ํจ๊ณผ์ ์ ๋ฆฌ๊ฐ ์์ผ๋ฏ๋ก ์ฌ์ฉ์๊ฐ ๋ค๋ฅธ ID๋ฅผ ์ ํํ ๋ ์ด๋ป๊ฒ ์ ์ ์์ต๋๊น? ์์ฒญ์ด ์์๋๋ก ๋์ฐฉํ์ง ์๊ณ ์๋ชป๋ ์ํ๋ฅผ ์ค์ ํ ์ํ์ด ์์ต๋๋ค. ๊ทธ๋์ ๊ทธ๊ฒ์ ๋ช ์ฌํด์ผ ํ ๊ฒ์ ๋๋ค. ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ๊ฐ ๊ตฌ์ฑ ์์ ์์ฒด์ ์๋ ๊ฒฝ์ฐ ์๋ต์์ setState๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด "๋ฌด์" ํ๋๊ทธ๋ฅผ ์ค์ ํ๋ ํจ๊ณผ ์ ๋ฆฌ ๊ธฐ๋ฅ์ ๊ฐ์ง ์ ์์ต๋๋ค. (๋ฌผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ธ๋ถ ์บ์๋ก ์ด๋ํ๋ ๊ฒ์ด ๋ ๋์ ์๋ฃจ์ ์ธ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค. Suspense๋ ๊ทธ๋ ๊ฒ ์๋ํฉ๋๋ค.)
์ด๋ฒคํธ ํธ๋ค๋ฌ์์ ๋์ผํ "๋ก๊ทธ"(์์ ์ ์ถ์ผ ์ ์๋ค๊ณ ๊ฐ์ )๋ฅผ ์ํํ๋ ๊ฒ์ด ๋ ์ ํฉํด ๋ณด์ ๋๋ค.
@gaearon ๋ด๊ฐ ๋ณผ ์์๋ ๋ฌธ์ ๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ์์ ์ํํ๋ ๊ฒ์ด ์ ๋ฐ์ดํธ๊ฐ ์ปค๋ฐ๋๊ธฐ ์ ์ ๋ถ์์ฉ์ด ๋ฐ์ํ๋ค๋ ๊ฒ์ ์๋ฏธํ๋ค๋ ๊ฒ์ ๋๋ค. ํด๋น ์ด๋ฒคํธ์ ๊ฒฐ๊ณผ๋ก ๊ตฌ์ฑ ์์๊ฐ ์ฑ๊ณต์ ์ผ๋ก ๋ค์ ๋ ๋๋ง๋๋ค๋ ์๊ฒฉํ ๋ณด์ฅ์ด ์์ผ๋ฏ๋ก ์ด๋ฒคํธ ์ฒ๋ฆฌ๊ธฐ์์ ์ํํ๋ ๊ฒ์ ์๊ธฐ์์กฐ์ผ ์ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด ์ฌ์ฉ์๊ฐ ์ ๊ฒ์์ด๋ฅผ ์ฑ๊ณต์ ์ผ๋ก ์ ์ถํ์ผ๋ฉฐ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๊ณ ์๋ค๋ ๊ฒ์ ๊ธฐ๋กํ๊ณ ์ถ์ ๊ฒฝ์ฐ์ ๋๋ค. ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ฌ ๊ตฌ์ฑ ์์๊ฐ ๋ฐ์ํ๋ฉด ํด๋น ๋ก๊ทธ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ง ์์์ผ๋ฉด ํฉ๋๋ค.
๊ทธ๋ฐ ๋ค์ ์ด ๋ถ์์ฉ์ด ๋น๋๊ธฐ์์ผ ์ ์์ผ๋ฏ๋ก useEffect
์ฌ์ฉํ๋ฉด ์ ๋ฆฌ ๊ธฐ๋ฅ์ด ์ ๊ณต๋๋ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค.
useReducer
์ ๋ฌธ์ ๋ ์์ต๋๋ค. ์ฌ๊ธฐ์ ๊ธฐ๋กํ๋ ค๋ ๊ฐ์ ์ด๋ฒคํธ ํธ๋ค๋ฌ์์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๋๋ ๊ทธ๊ฒ์ด ์ด๋ฏธ ์ฌ๋ฌ๋ถ์ ๋ ์ด๋์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค ๐
๋ ๊ฒฝ์ฐ ๋ชจ๋ ๊ถ์ฅํ๋ ์ ๊ทผ ๋ฐฉ์์ผ๋ก ์ถฉ๋ถํ ์ ์์ต๋๋ค. ๊ตฌ์ฑ ์ํ๋ฅผ ๊ตฌ์ฑํ๋ ๊ฐ๋ณ ๊ฐ์ ๊ณ์ ์ก์ธ์คํ ์ ์๋ ํ์์ผ๋ก ๊ตฌ์ฑ ์ํ๋ฅผ ์ ์ฅํฉ๋๋ค.
์ถ๊ฐ ๋งค๊ฐ๋ณ์๋ก ํจ์๋ฅผ ๋ํํ๊ณ ์ ๋ฌํ๊ธฐ ์ํ ํธ๋ฆฌํ ํํฌ๊ฐ ์์ต๋๋ค. ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
function useBoundCallback(fn, ...bound) {
return useCallback((...args) => fn(...bound, ...args), [fn, ...bound]);
}
(๋ช ๊ฐ์ง ์ถ๊ฐ ๊ธฐ๋ฅ์ด ์๊ธฐ ๋๋ฌธ์ ์ค์ ๋ก๋ ์กฐ๊ธ ๋ ๋ณต์กํ์ง๋ง ์์ ๋ด์ฉ์ ์ฌ์ ํ โโ๊ด๋ จ ๋ฌธ์ ๋ฅผ ๋ณด์ฌ์ค๋๋ค.)
์ฌ์ฉ ์ฌ๋ก๋ ๊ตฌ์ฑ ์์๊ฐ ์์ฑ์ ์์์๊ฒ ์ ๋ฌํด์ผ ํ๊ณ ์์์ด ํน์ ์์ฑ์ ์์ ํ ์ ์๊ธฐ๋ฅผ ์ํ๋ ๊ฒฝ์ฐ์ ๋๋ค. ์๋ฅผ ๋ค์ด, ๊ฐ ํญ๋ชฉ์ ํธ์ง ์ต์ ์ด ์๋ ๋ชฉ๋ก์ ๊ณ ๋ คํ์ญ์์ค. ๋ถ๋ชจ ๊ฐ์ฒด๋ ๊ฐ ์์์๊ฒ ๊ฐ์ ์ ๋ฌํ๊ณ ๊ฐ์ ํธ์งํ๋ ค๋ ๊ฒฝ์ฐ ํธ์ถํ ์ฝ๋ฐฑ ํจ์๋ฅผ ์ ๋ฌํฉ๋๋ค. ์์์ ์ด๋ค ํญ๋ชฉ ID๊ฐ ํ์๋๋์ง ์์ง ๋ชปํ๋ฏ๋ก ๋ถ๋ชจ๋ ์ด ๋งค๊ฐ๋ณ์๋ฅผ ํฌํจํ๋๋ก ์ฝ๋ฐฑ์ ์์ ํด์ผ ํฉ๋๋ค. ์ด๊ฒ์ ์์์ ๊น์ด์ ์ค์ฒฉ๋ ์ ์์ต๋๋ค.
์ด ํ๋ฆ์ ๊ฐ๋จํ ์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. https://codesandbox.io/s/vvv36834k5 ("์ด๋!"์ ํด๋ฆญํ๋ฉด ๊ตฌ์ฑ ์์ ๊ฒฝ๋ก๊ฐ ํฌํจ๋ ์ฝ์ ๋ก๊ทธ๊ฐ ํ์๋จ)
๋ฌธ์ ๋ ์ด ๊ท์น์์ 2๊ฐ์ ๋ฆฐํฐ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ค๋ ๊ฒ์ ๋๋ค.
React Hook(X)์ ๋๋ฝ๋ ์ข ์์ฑ: 'bound'๊ฐ ์์ต๋๋ค. ํฌํจํ๊ฑฐ๋ ์ข ์์ฑ ๋ฐฐ์ด์ ์ ๊ฑฐํ์ญ์์ค.
React Hook(X)์๋ ์ข ์์ฑ ๋ฐฐ์ด์ ์คํ๋ ๋ ์์๊ฐ ์์ต๋๋ค. ์ด๋ ์ฌ๋ฐ๋ฅธ ์ข ์์ฑ์ ์ ๋ฌํ๋์ง ์ฌ๋ถ๋ฅผ ์ ์ ์ผ๋ก ํ์ธํ ์ ์์์ ์๋ฏธํฉ๋๋ค.
๋งค๊ฐ๋ณ์ ๋ชฉ๋ก์ ์ฌ์ฉํ๋๋ก ๋ณ๊ฒฝํ๋ฉด(์ฆ, ์คํ๋ ๋ ์ฐ์ฐ์๋ฅผ ์ฌ์ฉํ์ง ์์) ๋งค๊ฐ๋ณ์๊ฐ ๋์ผํ๋๋ผ๋ ๋ชฉ๋ก์ด ํธ์ถํ ๋๋ง๋ค ์์ฑ๋๊ธฐ ๋๋ฌธ์ ๋ฉ๋ชจ์ด์ ์ด์ ์ด ์ญ์ ๋ฉ๋๋ค.
์๊ฐ:
์๋ ํ์ธ์ @gaearon , ๋ฐฉ๊ธ ์ด ๊ฒฝ๊ณ ๋ฅผ ๋ฐ์์ต๋๋ค.
Accessing 'myRef.current' during the effect cleanup will likely read a different ref value because by this time React has already updated the ref. If this ref is managed by React, store 'myRef.current' in a variable inside the effect itself and refer to that variable from the cleanup function.
์ด ๋ฉ์์ง๊ฐ ์ฝ๊ฐ ํผ๋์ค๋ฝ์ต๋๋ค. ์ ๋ฆฌ ์์ ref ํ์ฌ ๊ฐ์ด ํจ๊ณผ ๋ณธ๋ฌธ์ ๊ฐ๊ณผ ๋ค๋ฅผ ์ ์์์ ๊ฒฝ๊ณ ํ๋ ๊ฒ ๊ฐ์ต๋๋ค. ์ค๋ฅธ์ชฝ?
๊ทธ๋ ๋ค๋ฉด ์ด ๊ฒฝ๊ณ ๋ฅผ ๋ฌด์ํ๋ ๊ฒ์ด ์์ ํฉ๋๊น/ํฉ๋ฒ์ ์
๋๊น?
๋ด ๊ฒฝ์ฐ, ํฅ๋ฏธ๋ก์ด ๊ฒฝ์ฐ: CodeSandbox
์ปจํ
์คํธ: ์ผ๋ถ ์ฌ์ฉ์ ์ง์ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ ํํฌ. ๋๋ ๊ฒฝ์ ์กฐ๊ฑด๊ณผ ๋ง์ดํธ๋์ง ์์ ๊ตฌ์ฑ ์์์ ์
๋ฐ์ดํธ๋ฅผ ๋ชจ๋ ๋ฐฉ์งํ๊ธฐ ์ํด ref์์ ์นด์ดํฐ๋ฅผ ์ฌ์ฉํฉ๋๋ค.
ํจ์ ๋ด๋ถ์ ref ์ฝ๊ธฐ๋ฅผ ์จ๊ธฐ๊ฑฐ๋ ์ ๋ฆฌ ์ผ์ด์ค์ ๋ํ ๋ค๋ฅธ ๋ถ์ธ ์ฐธ์กฐ๋ฅผ ์์ฑํ์ฌ ์ด ๊ฒฝ๊ณ ๋ฅผ ์ฐํํ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ํ์ง๋ง ์ด ๊ฒฝ๊ณ ๋ฅผ ๋ฌด์ํ ์ ์๋ค๋ฉด ๋ถํ์ํ๊ฒ ์ฅํฉํฉ๋๋ค.
@ํผ๊ณคํ
์๋ฅผ ๋ค์ด ์ฌ์ฉ์๊ฐ ์ ๊ฒ์์ด๋ฅผ ์ฑ๊ณต์ ์ผ๋ก ์ ์ถํ์ผ๋ฉฐ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๊ณ ์๋ค๋ ๊ฒ์ ๊ธฐ๋กํ๊ณ ์ถ์ ๊ฒฝ์ฐ์ ๋๋ค. ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ฌ ๊ตฌ์ฑ ์์๊ฐ ๋ฐ์ํ๋ฉด ํด๋น ๋ก๊ทธ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ง ์์์ผ๋ฉด ํฉ๋๋ค.
์, ํ์ ์ฌ์ฉ ์ฌ๋ก์ฒ๋ผ ๋ค๋ฆฝ๋๋ค. ๋๋ถ๋ถ์ ์ฌ๋๋ค์ด "๋ถ์์ฉ"์ ์ํ ๋ ์ ์ถ๋ ์์์ ๋ดค๋ค๋ ์ฌ์ค์ด ์๋๋ผ ์์ ์ ์ถ ์์ฒด๋ฅผ ์๋ฏธํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ด ๊ฒฝ์ฐ ๋ด๊ฐ ์ ๊ณตํ ์๋ฃจ์ ์ด ๊ด์ฐฎ์ ๋ณด์ ๋๋ค.
@davidje13
๋ ๋ฒ์งธ๋ ์ ์ฉ๋ ๋ ์ฒซ ๋ฒ์งธ ์ค๋ฅ๋ฅผ ๋ณด์ฌ์ค ๊ฐ์น๊ฐ ์์ต๋๊น?
๋ฆฐํธ ๊ท์น ๋ณ๊ฒฝ ์ ์์ ๋ํ ์ ๋ฌธ์ ๋ฅผ ์ ์ถํ์ธ์.
ํนํ ์คํ๋ ๋ ์ฐ์ฐ์๊ฐ ์ฌ์ฉ๋๋ ์ฅ์์ ๋ํด ์ด ๊ท์น์ ๋นํ์ฑํํ ์ ์๋ ๋ฐฉ๋ฒ์ด ์์ต๋๊น?
์์ ์ด ํ๋ ์ผ์ ์๋ค๊ณ ์๊ฐํ๋ฉด ์ธ์ ๋ ์ง // eslint-disable-next-line react-hooks/exhaustive-deps
ํ ์ ์์ต๋๋ค.
ํจ์ ๋ด์์ ๋ณ์์ ์ ์ผํ ์ฌ์ฉ์ด ์คํ๋ ๋ ์ฐ์ฐ์์ ํจ๊ป ์ฌ์ฉ๋๋ ๊ฒฝ์ฐ ์ข ์์ฑ์์ ์คํ๋ ๋ ์ฐ์ฐ์๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์์ ํ๊ณ ๊ท์น์ด ์ด๋ฏธ ์ด๋ฅผ ๊ฐ์งํ๊ณ ์์ผ๋ฏ๋ก ํ์คํ ํ์ฉํด์ผ ํฉ๋๋ค.
์ ๋ฌธ์ ๋ฅผ ์ ์ถํ์ญ์์ค pls.
@CarlosGines
์ด ๋ฉ์์ง๊ฐ ์ฝ๊ฐ ํผ๋์ค๋ฝ์ต๋๋ค. ์ ๋ฆฌ ์์ ref ํ์ฌ ๊ฐ์ด ํจ๊ณผ ๋ณธ๋ฌธ์ ๊ฐ๊ณผ ๋ค๋ฅผ ์ ์์์ ๊ฒฝ๊ณ ํ๋ ๊ฒ ๊ฐ์ต๋๋ค. ์ค๋ฅธ์ชฝ?
์.
๊ทธ๋ ๋ค๋ฉด ์ด ๊ฒฝ๊ณ ๋ฅผ ๋ฌด์ํ๋ ๊ฒ์ด ์์ ํฉ๋๊น/ํฉ๋ฒ์ ์ ๋๊น?
์ .. ๋ฒ๊ทธ๋ก ์ด์ด์ง๋ ๊ฒฝ์ฐ๊ฐ ์๋๋๋ค. ๐
์ปจํ ์คํธ: ์ผ๋ถ ์ฌ์ฉ์ ์ง์ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ ํํฌ. ๋๋ ๊ฒฝ์ ์กฐ๊ฑด๊ณผ ๋ง์ดํธ๋์ง ์์ ๊ตฌ์ฑ ์์์ ์ ๋ฐ์ดํธ๋ฅผ ๋ชจ๋ ๋ฐฉ์งํ๊ธฐ ์ํด ref์์ ์นด์ดํฐ๋ฅผ ์ฌ์ฉํฉ๋๋ค.
์, ์๋ง๋ ์ด ์ฌ์ฉ ์ฌ๋ก๊ฐ ํฉ๋ฒ์ผ ๊ฒ์ ๋๋ค. Pls๋ฅผ ๋ ผ์ํ๊ธฐ ์ํด ์๋ก์ด ๋ฌธ์ ๋ฅผ ์ ์ถํ์๊ฒ ์ต๋๊น?
์ถฉ๋ถํ ํผ๋๋ฐฑ์ ๋ฐ๊ณ ํตํฉ๋์์ผ๋ฏ๋ก ์ด ๋ฌธ์ ๋ฅผ ์ ๊ทธ๊ฒ ์ต๋๋ค.
์ผ๋ฐ์ ์ธ ์ง๋ฌธ ๋ฐ ๋ต๋ณ: https://github.com/facebook/react/issues/14920#issuecomment -471070149
useEffect
๋ฐ ์ข
์์ฑ์ ๋ํด ์์ธํ ์์๋ณด๋ ค๋ฉด ์ฌ๊ธฐ๋ฅผ https://overreacted.io/a-complete-guide-to-useeffect/
๊ณง ๋ฌธ์์ ๋ ๋ง์ ํญ๋ชฉ์ ์ถ๊ฐํ ์์ ์ ๋๋ค.
๊ท์น์์ ๋ฌด์ธ๊ฐ๋ฅผ ๋ณ๊ฒฝํ๊ณ ์ถ๊ฑฐ๋ ๊ทํ์ ์ฌ๋ก๊ฐ ํฉ๋ฒ์ ์ธ์ง ํ์คํ์ง ์์ ๊ฒฝ์ฐ ์ ๋ฌธ์ ๋ฅผ ์ ์ถํ์ญ์์ค.
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
์ฐ๋ฆฌ๋ ์ค๋ @threepointone ์ผ๋ก
Lint ๊ท์น์์ ์์ ๋จ
๊ด๋ จ ์๋
useEffect
์ข ์์ฑ์ด ๊ท์น์ ํฉ๋ฒ์ ์ธ ์๋๋ฆฌ์ค๊ฐ ์์ผ๋ฏ๋ก ๋ ์ด์ "์ธ๋ถ" dep๋ฅผ
useEffect
์ถ๊ฐํ๋ ๊ฒ์ ๋ฐฉ์งํ์ง ์์ต๋๋ค.๋์ผํ ๊ตฌ์ฑ ์์์ ์์ง๋ง ํจ๊ณผ ์ธ๋ถ์์ ์ ์๋ ๊ธฐ๋ฅ
Linter๋ ์ง๊ธ ์์ ํ ๊ฒฝ์ฐ์ ๋ํด ๊ฒฝ๊ณ ํ์ง ์์ง๋ง ๋ค๋ฅธ ๋ชจ๋ ๊ฒฝ์ฐ์๋ ๋ ๋์ ์ ์์ ์ ๊ณตํฉ๋๋ค(์: ํจ๊ณผ ๋ด์์ ํจ์๋ฅผ ์ด๋ํ๊ฑฐ๋
useCallback
๋ํ).์ฌ์ฉ์ ์ฝ๋์์ ์์ ํ ๊ฐ์น๊ฐ ์์
props ๋ณ๊ฒฝ ์ ์ํ ์ฌ์ค์
์ด๊ฒ์ ๋ ์ด์ ๋ฆฐํธ ์๋ฐ์ ์์ฑํ์ง ์์ง๋ง props์ ๋ํ ์๋ต์ผ๋ก ์ํ๋ฅผ ์ฌ์ค์ ํ๋ ๊ด์ฉ์ ๋ฐฉ๋ฒ์ ๋ค๋ฆ ๋๋ค . ์ด ์๋ฃจ์ ์๋ ์ผ๊ด์ฑ ์๋ ๋ ๋๋ง์ด ์ถ๊ฐ๋ก ํฌํจ๋๋ฏ๋ก ๋ฐ๋์งํ์ง ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค.
"๋ด ๋น ๊ธฐ๋ฅ ๊ฐ์ ์ผ์ ํฉ๋๋ค"
ํํฌ๋ ๊ฐ๋ฅํ ํ ์ ํํจ์ ์ถ๊ตฌํฉ๋๋ค. ๋น์ ์ด (๊ฒฝ์ฐ์ ๋ฐ๋ผ์๋ ์๋ต ํ ์ ์์) deps๋ฅผ ์ง์ ํ๋ฉด, ์ฐ๋ฆฌ๋ ๊ฐํ๊ฒ ๋น์ ์ด ๋ณ๊ฒฝ๋์ง ์์ต๋๋ค ์๊ฐ๋ ์ฌ๋์ ํฌํจํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ์, ์ด
useDebounce
์์์๋ ์ง์ฐ์ด ๋ณ๊ฒฝ ๋์ง ์์ ๊ฒ์ ๋๋ค. ํ์ง๋ง ๋ฒ๊ทธ๊ฐ ๋ฐ์ํ๋ฉด ์ฌ์ ํ ๋ฒ๊ทธ์ด์ง๋ง Hook์ ์ด๋ฅผ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค. ์ด๊ฒ์ ๋ค๋ฅธ ์๋๋ฆฌ์ค์์๋ ๋ํ๋ฉ๋๋ค. (์: Hooks๋ ๋ชจ๋ ๊ฐ์ด ๋์ ์ผ๋ก ์ฒ๋ฆฌ๋๊ธฐ ๋๋ฌธ์ ํซ ๋ฆฌ๋ก๋ฉ๊ณผ ํจ์ฌ ๋ ํธํ๋ฉ๋๋ค.)ํน์ ๊ฐ์ด ์ ์ ์ด๋ผ๊ณ ์ ๋์ ์ผ๋ก ์ฃผ์ฅํ๋ค๋ฉด ๊ฐ์ ํ ์ ์์ต๋๋ค.
๊ฐ์ฅ ์์ ํ ๋ฐฉ๋ฒ์ API์์ ๋ช ์์ ์ผ๋ก ์ํํ๋ ๊ฒ์ ๋๋ค.
๊ทธ๋ฐ ๋ค์ render ์์ ๋ฃ์ง ์๋ ํ ๋ถ๋ช ํ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค. (์ด๊ฒ์ Hook์ ๊ด์ฉ์ ์ฌ์ฉ๋ฒ์ด ์๋๋๋ค.) ํ์ง๋ง
<Slider min={50} />
can never change ๋ผ๋ ๋ง์ ์ค์ ๋ก ์ ํจํ์ง ์์ต๋๋ค โ ๋๊ตฐ๊ฐ ๊ทธ๊ฒ์<Slider min={state ? 50 : 100} />
์ฝ๊ฒ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค. ์ค์ ๋ก ๋๊ตฐ๊ฐ๋ ๋ค์๊ณผ ๊ฐ์ด ํ ์ ์์ต๋๋ค.๋๊ตฐ๊ฐ
isCelsius
์ํ๋ฅผ ์ ํํ๋ฉดmin
๋ณ๊ฒฝ๋์ง ์๋๋ค๊ณ ๊ฐ์ ํ๋ ๊ตฌ์ฑ ์์๊ฐ ์ ๋ฐ์ดํธ๋์ง ์์ต๋๋ค. ์ด ๊ฒฝ์ฐSlider
๊ฐ ๋์ผํ์ง ์ฌ๋ถ๋ ๋ถ๋ช ํ์ง ์์ต๋๋ค(๊ทธ๋ฌ๋ ํธ๋ฆฌ์์ ๋์ผํ ์์น์ ์๊ธฐ ๋๋ฌธ์ผ ๊ฒ์ ๋๋ค). ๋ฐ๋ผ์ ์ด๊ฒ์ ์ฝ๋๋ฅผ ๋ณ๊ฒฝํ๋ ์ธก๋ฉด์์ ์ค์ํ ๋ฐํ์ ๋๋ค. React์ ์ฃผ์ ํฌ์ธํธ๋ ์ ๋ฐ์ดํธ๊ฐ ์ด๊ธฐ ์ํ์ฒ๋ผ ๋ ๋๋ง๋๋ค๋ ๊ฒ์ ๋๋ค(๋ณดํต ์ด๋ ๊ฒ์ด ์ด๋ ์ํ์ธ์ง ์ ์ ์์). prop ๊ฐ B๋ฅผ ๋ ๋๋งํ๋ prop ๊ฐ A์์ B๋ก ์ด๋ํ๋ ์๊ด์์ด ๋์ผํ๊ฒ ๋ณด์ด๊ณ ์๋ํด์ผ ํฉ๋๋ค.์ด๊ฒ์ ๋ฐ๋์งํ์ง ์์ง๋ง ๊ฒฝ์ฐ์ ๋ฐ๋ผ ์ ์ฉ ๋ฉ์ปค๋์ฆ์ ๊ฐ์ด ๋ณ๊ฒฝ๋ ๋ ๊ฒฝ๊ณ ํ๋(๊ทธ๋ฌ๋ ์ฒซ ๋ฒ์งธ ๊ฐ์ ์ ๊ณตํ๋) ํํฌ์ผ ์ ์์ต๋๋ค. ์ ์ด๋ ๊ทธ๋๋ ์ฃผ๋ชฉ๋ฐ์ ๊ฐ๋ฅ์ฑ์ด ๋ ํฝ๋๋ค.
์ ๋ฐ์ดํธ๋ฅผ ์ฒ๋ฆฌ ํ ์ ์๋ ํฉ๋ฒ์ ์ธ ๊ฒฝ์ฐ๋ ์์ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด jQuery ํ๋ฌ๊ทธ์ธ์ด๋ DOM API์ ๊ฐ์ด ํ์ ์์ค API๊ฐ ์ง์ํ์ง ์๋ ๊ฒฝ์ฐ์ ๊ฐ์ต๋๋ค. ์ด ๊ฒฝ์ฐ ๊ตฌ์ฑ ์์์ ์๋น์๊ฐ ์ดํดํ ์ ์๋๋ก ๊ฒฝ๊ณ ๊ฐ ์ฌ์ ํ ์ ์ ํฉ๋๋ค. ๋๋ ํธํ๋์ง ์๋ ์ ๋ฐ์ดํธ์์
key
๋ฅผ ์ฌ์ค์ ํ๋ ๋ํผ ๊ตฌ์ฑ ์์๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค. ์ฌ๋ผ์ด๋๋ ์ฒดํฌ๋ฐ์ค์ ๊ฐ์ ๋ฆฌํ ๊ตฌ์ฑ์์์ ๋ ์ ํฉํ ๊ฒ์ ๋๋ค."๋ด ๊ธฐ๋ฅ ๊ฐ์ ์ผ์ ํฉ๋๋ค"
์ฐ์ , ๊ทธ๊ฒ์ด ์ผ์ ํ๊ณ ์ต์์ ๋ฒ์๋ก ํธ์ด์คํธ๋๋ฉด ๋ฆฐํฐ๋ ๋ถํํ์ง ์์ ๊ฒ์ ๋๋ค. ๊ทธ๋ฌ๋ ๊ทธ๊ฒ์ ์ํ์ด๋ ์ปจํ ์คํธ์์ ์ค๋ ๊ฒ์๋ ๋์์ด ๋์ง ์์ต๋๋ค.
๊ทธ๊ฒ์ด ์ง์ ์ผ๋ก ์ผ์ ํ๋ค๋ฉด deps๋ก ์ง์ ํด๋ ๋ฌธ์ ๊ฐ ๋์ง ์์ต๋๋ค. ์ฌ์ฉ์ ์ ์ Hook ๋ด๋ถ์
setState
ํจ์๊ฐ ๊ตฌ์ฑ ์์๋ก ๋ฐํ๋ ๋ค์ ํจ๊ณผ์์ ํธ์ถํ๋ ๊ฒฝ์ฐ์ ๊ฐ์ด. Lint ๊ท์น์ ์ด์ ๊ฐ์ ๊ฐ์ ์ฐธ์กฐ๋ฅผ ์ดํดํ ๋งํผ ๋๋ํ์ง ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๋ค๋ฅธ ํํธ์ผ๋ก ๋๊ตฌ๋ ์ง ๋ฐํํ๊ธฐ ์ ์ ๋์ค์ ํด๋น ์ฝ๋ฐฑ์ ๋ํํ ์ ์์ผ๋ฉฐ ๊ทธ ์์ ์๋ ๋ค๋ฅธ prop ๋๋ state๋ฅผ ์ฐธ์กฐํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ฉด ์ผ์ ํ์ง ์์ต๋๋ค! ๊ทธ๋ฆฌ๊ณ ์ด๋ฌํ ๋ณ๊ฒฝ ์ฌํญ์ ์ฒ๋ฆฌํ์ง ๋ชปํ๋ฉด ๋ถ์พํ prop/state ๋ฒ๊ทธ๊ฐ ๋ฐ์ํฉ๋๋ค. ๋ฐ๋ผ์ ์ง์ ํ๋ ๊ฒ์ด ๋ ๋์ ๊ธฐ๋ณธ๊ฐ์ ๋๋ค.๊ทธ๋ฌ๋ ํจ์ ๊ฐ์ด ๋ฐ๋์ ์ผ์ ํ๋ค๋ ๊ฒ์ ์๋ชป๋ ์๊ฐ์ ๋๋ค. ์์ฒด์ ์ธ ๋ฒ๊ทธ ๋ฒ์ ๋ฅผ ์์ฑํ์ง๋ง ๋ฉ์๋ ๋ฐ์ธ๋ฉ์ผ๋ก ์ธํด ํด๋์ค์์ ๋ ์์ฃผ ์ผ์ ๋ด๋ถ ๋ก ์ด๋ํ๊ฑฐ๋
useCallback
๋ํ)์ด๊ฒ์ ๋ฐ๋ ์คํํธ๋ผ์๋ ๋ฌดํ ๋ฃจํ๊ฐ ๋ฐ์ํ๋ ๋ฌธ์ ๊ฐ ์์ต๋๋ค(ํจ์ ๊ฐ์ ํญ์ ๋ณ๊ฒฝ๋จ). ๊ฐ๋ฅํ ๊ฒฝ์ฐ(๋์ผํ ๊ตฌ์ฑ ์์์์) ์ด์ Lint ๊ท์น์์ ์ด๋ฅผ ํฌ์ฐฉํ๊ณ ์์ ์ฌํญ์ ์ ์ํฉ๋๋ค. ๊ทธ๋ฌ๋ ๋ช ๋จ๊ณ ์๋๋ก ๋ฌด์ธ๊ฐ๋ฅผ ํต๊ณผํ๋ฉด ๊น๋ค๋กญ์ต๋๋ค.
์ฌ์ ํ
useCallback
๋ก ๊ฐ์ธ์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์ต๋๋ค. ๊ธฐ์ ์ ์ผ๋ก ํจ์๊ฐ ๋ณ๊ฒฝ๋๋ ๊ฒ์ ์ ํจํ๋ฉฐ ๋ฒ๊ทธ์ ์ํ ์์ด ์ด ๊ฒฝ์ฐ๋ฅผ ๋ฌด์ํ ์ ์์ต๋๋ค.onChange={shouldHandle ? handleChange : null}
๋๋ ๊ฐ์ ์์น์์foo ? <Page fetch={fetchComments /> : <Page fetch={fetchArticles />
๋ ๋๋ง ๋ฑ. ๋๋ ์์ ๊ตฌ์ฑ ์์ ์ํ๋ฅผ ๋ซ๋fetchComments
์์ต๋๋ค. ๋ณ๊ฒฝ ๋ ์ ์์ต๋๋ค. ํด๋์ค๋ฅผ ์ฌ์ฉํ๋ฉด ๋์์ด ์๋์ผ๋ก ๋ณ๊ฒฝ๋์ง๋ง ํจ์ ์ฐธ์กฐ๋ ๋์ผํ๊ฒ ์ ์ง๋ฉ๋๋ค. ๋ฐ๋ผ์ ์๋ ๋ ํด๋น ์ ๋ฐ์ดํธ๋ฅผ ๋์น ๊ฒ์ ๋๋ค. ์๋ ์๊ฒ ๋ ๋ง์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ๊ฒ ์ธ์๋ ์ต์ ์ด ์์ต๋๋ค. ํจ์ ๊ตฌ์ฑ ์์์useCallback
๋ฅผ ์ฌ์ฉํ๋ฉด ํจ์ ID ์์ฒด๊ฐ ๋ณ๊ฒฝ๋์ง๋ง ํ์ํ ๊ฒฝ์ฐ์๋ง ๋ณ๊ฒฝ๋ฉ๋๋ค. ๋ฐ๋ผ์ ์ด๋ ์ ์ฉํ ์์ฑ์ด๋ฉฐ ํผํด์ผ ํ ์ฅ์ ๋ฌผ์ด ์๋๋๋ค.๋ฌดํ ๋น๋๊ธฐ ๋ฃจํ๋ฅผ ๊ฐ์งํ๊ธฐ ์ํ ๋ ๋์ ์๋ฃจ์ ์ ์ถ๊ฐํด์ผ ํฉ๋๋ค. ๊ฐ์ฅ ํผ๋์ค๋ฌ์ด ์ธก๋ฉด์ ์ํํด์ผ ํฉ๋๋ค. ํฅํ ์ด์ ๋ํ ๊ฐ์ง ๊ธฐ๋ฅ์ ์ถ๊ฐํ ์ ์์ต๋๋ค. ๋ค์๊ณผ ๊ฐ์ด ์ง์ ์์ฑํ ์๋ ์์ต๋๋ค.
์ด๊ฒ์ ์ด์์ ์ด์ง ์์ผ๋ฉฐ ์ฐ๋ฆฌ๋ ์ด๊ฒ์ ๋ ์ฐ์ํ๊ฒ ์ฒ๋ฆฌํ๋ ๊ฒ์ ๋ํด ์๊ฐํ ํ์๊ฐ ์์ต๋๋ค. ๋ด๊ฐ ์ข์ํ๋ ๊ฒฝ์ฐ ๋์ ์ด ๊ฝค ๋ถ์พํ์ ๋๋ค. ๊ท์น์ ์๋ฐํ์ง ์๊ณ ์์ ํ๋ ๊ฒ์
rules
์ ์ ์ผ๋ก ๋ง๋๋ ๊ฒ์ ๋๋ค(์: API๋ฅผcreateTextInput(rules)
๋ก ๋ณ๊ฒฝํ๊ณregister
๋ฐunregister
์useCallback
. ๋ ์ข์ ๋ฐฉ๋ฒ์register
๋ฐunregister
๋ฅผ ์ ๊ฑฐํ๊ณdispatch
๋ง ๋ฃ๋ ๋ณ๋์ ์ปจํ ์คํธ๋ก ๋ฐ๊พธ๋ ๊ฒ์ ๋๋ค. ๊ทธ๋ฐ ๋ค์ ์ฝ๋ ๊ฒ๊ณผ ๋ค๋ฅธ ๊ธฐ๋ฅ ID๋ฅผ ๊ฐ์ง ์์ ๊ฒ์์ ๋ณด์ฅํ ์ ์์ต๋๋ค.๊ณต๊ธ์๊ฐ ์ ๊ตฌ์ฑ ์์๊ฐ ๋ฑ๋ก๋์ง ์์์ง๋ง ์์ฒด ๋ถ๋ชจ๊ฐ ์ ๋ฐ์ดํธ๋ ๊ฒฝ์ฐ ๋ฐ๋ณต์ ์ผ๋ก ์ฌํ ๋ง์ ๊ณ์ฐ์ ์ํํ๊ธฐ ๋๋ฌธ์ ์ด์จ๋ ์ปจํ ์คํธ ๊ฐ์
useMemo
๋ฅผ ์ถ๊ฐํ๊ณ ์ถ์ ๊ฒ์ ๋๋ค. ๋ฐ๋ผ์ ์ด๋ฌํ ์ข ๋ฅ์ ๋ฌธ์ ๋ ๊ทธ๋ ์ง ์์ผ๋ฉด ๋ ๋์ ๋์ง ์์ ์ ์๋ ๋ฌธ์ ๋ฅผ ๋ฃ์ต๋๋ค. ๋๋ ์ด๊ฒ์ด ์ผ์ด๋ ๋ ์ฐ๋ฆฌ๊ฐ ๋์ฑ ๋๋๋ฌ์ง๊ฒ ๋ง๋ค ํ์๊ฐ ์๋ค๋ ๋ฐ ๋์ํ์ง๋ง.ํจ์ ์ข ์์ฑ์ ์์ ํ ๋ฌด์ํ๋ฉด ํจ์ ๊ตฌ์ฑ ์์์ Hooks์์ ๋ ๋์ ๋ฒ๊ทธ๋ก ์ด์ด์ง๋๋ค. ๊ทธ๋ ๊ฒ ํ๋ฉด ๊ณ์ ์ค๋๋ props์ state๊ฐ ํ์๋๊ธฐ ๋๋ฌธ์ ๋๋ค. ๊ทธ๋ฌ๋ ํ ์ ์์ ๋ ํ์ง ๋ง์ญ์์ค.
๋ณตํฉ ๊ฐ์น ๋ณํ์ ๋์ํ๊ธฐ
์ด ์์ ๊ฐ ๋ณธ์ง์ ์ผ๋ก ์ด๋ฒคํธ ํธ๋ค๋ฌ์ ๋ํ ํจ๊ณผ๋ฅผ ์ฌ์ฉํ๋ ์ด์ ๊ฐ ์ด์ํฉ๋๋ค. ์ด๋ฒคํธ ํธ๋ค๋ฌ์์ ๋์ผํ "๋ก๊ทธ"(์์ ์ ์ถ์ผ ์ ์๋ค๊ณ ๊ฐ์ )๋ฅผ ์ํํ๋ ๊ฒ์ด ๋ ์ ํฉํด ๋ณด์ ๋๋ค. ๊ตฌ์ฑ ์์๊ฐ ๋ง์ดํธ ํด์ ๋ ๋ ์ด๋ค ์ผ์ด ๋ฐ์ํ๋์ง ์๊ฐํ๋ฉด ํนํ ๊ทธ๋ ์ต๋๋ค. ํจ๊ณผ๊ฐ ์์ฝ๋ ์งํ ๋ง์ดํธ๋ฅผ ํด์ ํ๋ฉด ์ด๋ป๊ฒ ๋ฉ๋๊น? ์์ ์ ์ถ๊ณผ ๊ฐ์ ์ผ์ ์ด ๊ฒฝ์ฐ์ "๋ฐ์ํ์ง ์์์ผ" ํฉ๋๋ค. ๊ทธ๋์ ํจ๊ณผ๊ฐ ์๋ชป๋ ์ ํ์ผ ์ ์๋ ๊ฒ ๊ฐ์ต๋๋ค.
์ฆ,
fullName
๋ฅผsetSubmittedData({firstName, lastName})
๋์[submittedData]
๋ก ๋ง๋ค๊ณfirstName
์ฝ์ ์ ์๋ ์ข ์์ฑ์ ํตํด ์๋ํ ์์ ์ ๊ณ์ ์ํํ ์ ์์ต๋๋คlastName
.ํ์/๋ ๊ฑฐ์ ์ฝ๋์ ํตํฉ
jQuery ํ๋ฌ๊ทธ์ธ ๋๋ ์์ DOM API์ ๊ฐ์ ํ์ ํญ๋ชฉ๊ณผ ํตํฉํ ๋ ์ฝ๊ฐ์ ๋ถํธํจ์ด ์์๋ ์ ์์ต๋๋ค. ์ฆ, ํด๋น ์์ ์์ ํจ๊ณผ ๋ฅผ ์ข ๋ ํตํฉํ ์ ์์ ๊ฒ์ผ๋ก ๊ธฐ๋ํฉ๋๋ค.
์๋ฌด๋ ์์ง ์์์ผ๋ฉด ์ข๊ฒ ์ด! ๋ด๊ฐ ํ ๊ฒฝ์ฐ ๋๋ ๋ญ๊ฐ ๋ช ํํ์ง ์์ ๊ฒฝ์ฐ ์๋ ค์ฃผ์ญ์์ค. ์ฐ๋ฆฌ๋ ๊ณง ์ด๊ฒ์ ๊ตํ์ ์ผ๋ถ ๋ฌธ์๋ก ๋ฐ๊พธ๋ ค๊ณ ๋ ธ๋ ฅํ ๊ฒ์ ๋๋ค.