ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [React] ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ์˜ React hooks
    React 2020. 6. 23. 20:17

    ๐ŸŒˆ Hook์˜ ๊ฐœ์š”

    Hook๊ฐ€ React ๋ฒ„์ „ 16.8์— ์ƒˆ๋กญ๊ฒŒ ์ถ”๊ฐ€๋˜์—ˆ๋‹ค. Hook๋ฅผ ์ด์šฉํ•˜์—ฌ Class๋ฅผ ์ž‘์„ฑํ•  ํ•„์š” ์—†์ด ์ƒํƒœ ๊ฐ’๊ณผ ์—ฌ๋Ÿฌ React์˜ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

    ๐Ÿ”ธ Hook๋ฅผ ๋งŒ๋“ค๊ฒŒ ๋œ ๋™๊ธฐ

    1. ์ปดํฌ๋„ŒํŠธ ์‚ฌ์ด์—์„œ ์ƒํƒœ์™€ ๊ด€๋ จ๋œ ๋กœ์ง์„ ์žฌ์‚ฌ์šฉํ•˜๊ธฐ ์–ด๋ ต๋‹ค.
    2. ๋ณต์žกํ•œ ์ปดํฌ๋„ŒํŠธ๋“ค์€ ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ต๋‹ค.
    3. Class์€ ์‚ฌ๋žŒ๊ณผ ๊ธฐ๊ณ„๋ฅผ ํ˜ผ๋™์‹œํ‚จ๋‹ค.

    ๐ŸŒˆ Hook์˜ ๊ทœ์น™

    Hook์„ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ๋‘ ๊ฐ€์ง€ ๊ทœ์น™์„ ์ค€์ˆ˜ํ•ด์•ผ ํ•œ๋‹ค.
    ์ด๋Ÿฌํ•œ ๊ทœ์น™์„ ์ž๋™์œผ๋กœ ์ง€์ผœ์ฃผ๋Š” linter ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ์žˆ๋‹ค.
    ์œ„ ESLint ํ”Œ๋Ÿฌ๊ทธ์ธ์€ create react app์— ๊ธฐ๋ณธ์ ์œผ๋กœ ํฌํ•จํ•˜๊ณ  ์žˆ๋‹ค.

    1. 1. ์ตœ์ƒ์œ„์—์„œ๋งŒ Hook์„ ํ˜ธ์ถœํ•ด์•ผ ํ•œ๋‹ค.
      ๋ฐ˜๋ณต๋ฌธ, ์กฐ๊ฑด๋ฌธ ํ˜น์€ ์ค‘์ฒฉ๋œ ํ•จ์ˆ˜ ๋‚ด์—์„œ Hook์„ ํ˜ธ์ถœํ•˜์ง€ ์•Š๋Š”๋‹ค.
    2. 2. ์˜ค์ง React ํ•จ์ˆ˜ ๋‚ด์—์„œ Hook์„ ํ˜ธ์ถœํ•ด์•ผ ํ•œ๋‹ค.
      Hook์„ ์ผ๋ฐ˜์ ์ธ javascript ํ•จ์ˆ˜์—์„œ ํ˜ธ์ถœํ•˜์ง€ ๋ง์•„์•ผ ํ•œ๋‹ค.

    ๐ŸŒˆ useState

    • ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ Hook๋กœ ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ์—์„œ ๊ฐ€๋ณ€์ ์ธ ์ƒํƒœ๋ฅผ ์ง€๋‹ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด ์ค€๋‹ค.

    • useState ํ•จ์ˆ˜์˜ ํŒŒ๋ผ๋ฏธํ„ฐ์—๋Š” ์ƒํƒœ์˜ ๊ธฐ๋ณธ๊ฐ’์„ ๋„ฃ์–ด์ฃผ๋Š” ๊ฒƒ์œผ๋กœ ์ดˆ๊ธฐ ๋ Œ๋”๋ง ์‹œ์— ์‚ฌ์šฉํ•˜๋Š” ๊ฐ’์ด๋‹ค.

    • ๊ทธ ์ดํ›„์˜ ๋ Œ๋”๋ง ์‹œ์—๋Š” ์ด ๊ฐ’์€ ๋ฌด์‹œ๋œ๋‹ค.

      const [value,setValue] = useState(0);
    • useState ํ•จ์ˆ˜๋Š” ํ˜ธ์ถœ๋˜๋ฉด ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•˜๋Š”๋ฐ ๋ฐฐ์—ด์˜ ์ฒซ ๋ฒˆ์งธ ์›์†Œ๋Š” ์ƒํƒœ ๊ฐ’, ๋‘ ๋ฒˆ์งธ ์›์†Œ๋Š” ์ƒํƒœ๋ฅผ ์„ค์ •ํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค.

    • setValue ํ•จ์ˆ˜๋Š” value๋ฅผ ๊ฐฑ์‹ ํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

      setValue(newValue);
    • ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ

         class Example extends React.Component {
            constructor(props) {
              super(props);
              this.state = {
                value: 0
              };
            }
            render() {
              return (
                <div>
                  <p> ์นด์šดํ„ฐ ๊ฐ’ {this.state.value} ์ž…๋‹ˆ๋‹ค. </p>
                  <button onClick={() => this.setState({ count: this.state.value + 1 })}>+1</button>
                  <button onClick={() => this.setState({ count: this.state.value - 1 })}>-1</button>
                </div>
              );
            }
          }
    • ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ

        const Counter = () => {
          const [value,setValue] = useState(0);
      
          return(
              <div>
                  <p> ์นด์šดํ„ฐ ๊ฐ’์€ <b>{value}</b>์ž…๋‹ˆ๋‹ค. </p>
                  <button onClick={() => setValue(value+1)}>+1</button>
                  <button onClick={() => setValue(value-1)}>-1</button>
              </div>
          )
    • ๐Ÿ”ธ state ๊ฐฑ์‹ ์˜ ์ทจ์†Œ
      State Hook์„ ํ˜„์žฌ์˜ state์™€ ๋™์ผํ•œ ๊ฐ’์œผ๋กœ ๊ฐฑ์‹ ํ•˜๋Š” ๊ฒฝ์šฐ React๋Š” ์ž์‹์„ ๋ Œ๋”๋ง ํ•œ๋‹ค๊ฑฐ๋‚˜ ๋ฌด์—‡์„ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์„ ํšŒํ”ผํ•˜๊ณ  ๊ทธ ์ฒ˜๋ฆฌ๋ฅผ ์ข…๋ฃŒํ•œ๋‹ค.(React๋Š” Object.is ๋น„๊ต ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•œ๋‹ค.)

     

    Object.is()

    Object.is() ๋ฉ”์„œ๋“œ๋Š” ๋‘ ๊ฐ’์ด ๊ฐ™์€ ๊ฐ’์ธ์ง€ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค.

    developer.mozilla.org

    ๐ŸŒˆ useEffect

    • useEffect์— ์ „๋‹ฌ๋œ ํ•จ์ˆ˜๋Š” ํ™”๋ฉด์— ๋ Œ๋”๋ง์ด ์™„๋ฃŒ๋œ ํ›„์— ์ˆ˜ํ–‰๋˜๊ฒŒ ๋œ๋‹ค.

    • ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋ง ๋  ๋•Œ๋งˆ๋‹ค ํŠน์ • ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋„๋ก ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋Š” Hook์ด๋‹ค.

    • ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ์˜ componentDidMount์™€ componentDidUpdate๋ฅผ ํ•ฉ์นœ ํ˜•ํƒœ๋ž‘ ๊ฐ™๋‹ค.

    • useEffect()๋Š” ๊ฐ’์ด ์—…๋ฐ์ดํŠธ๋  ๋•Œ๋งˆ๋‹ค ์‹คํ–‰๋˜๋Š”๋ฐ ํ™”๋ฉด์— ๋งจ ์ฒ˜์Œ ๋ Œ๋”๋ง ๋  ๋•Œ๋งŒ ์‹คํ–‰ํ•˜๊ณ , ์—…๋ฐ์ดํŠธ๋  ๋•Œ๋Š” ์‹คํ–‰๋˜์ง€ ์•Š๊ฒŒ ํ•˜๋ ค๋ฉด ํ•จ์ˆ˜์˜ ๋‘ ๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋น„์–ด ์žˆ๋Š” ๋ฐฐ์—ด์„ ๋„ฃ์–ด ์ฃผ๋ฉด ๋œ๋‹ค.

    • ์ด ๋ฐฐ์—ด์€ effect๊ฐ€ ์ข…์†๋˜์–ด ์žˆ๋Š” ๊ฐ’์˜ ๋ฐฐ์—ด์ด์ง€๋งŒ, ๋นˆ ๋ฐฐ์—ด ์‹œ์— ์–ด๋–ค ๊ฐ’์—๋„ ์˜์กดํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ, ๋‹ค์‹œ ์‹คํ–‰ํ•  ํ•„์š”๊ฐ€ ์ „ํ˜€ ์—†์–ด์ง„๋‹ค.

        useEffect(() => {
            console.log({ name, nickName })
        },[])
    • ํŠน์ • ๊ฐ’์ด ์—…๋ฐ์ดํŠธ๋  ๋•Œ๋งŒ ์‹คํ–‰ํ•˜๊ณ  ์‹ถ์œผ๋ฉด ๋‘ ๋ฒˆ์งธ ํŒŒ๋ฆฌ๋ฏธํ„ฐ๋กœ ์ „๋‹ฌ๋˜๋Š” ๋ฐฐ์—ด ์•ˆ์— ๊ฒ€์‚ฌํ•˜๊ณ  ์‹ถ์€ ๊ฐ’์„ ๋„ฃ์–ด ์ฃผ๋ฉด ๋œ๋‹ค.

      useEffect(() => {
      console.log(name);
      },[name])

    ๐Ÿ”ธ effect ์ •๋ฆฌ

    • ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์–ธ๋งˆ์šดํŠธ๋˜๊ธฐ ์ „์ด๋‚˜ ์—…๋ฐ์ดํŠธ๋˜๊ธฐ ์ง์ „์— ์–ด๋–ค ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด useEffect์—์„œ ์ •๋ฆฌ(clean-up) ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ด ์ฃผ์–ด์•ผ ํ•œ๋‹ค.

    • ์ •๋ฆฌ ํ•จ์ˆ˜๋Š” ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ๋ฐฉ์ง€๋ฅผ ์œ„ํ•ด UI์—์„œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ œ๊ฑฐํ•˜๊ธฐ ์ „์— ์ˆ˜ํ–‰๋œ๋‹ค.

    • ๋งŒ์•ฝ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์—ฌ๋Ÿฌ ๋ฒˆ ๋ Œ๋”๋ง ๋œ๋‹ค๋ฉด ๋‹ค์Œ effect๊ฐ€ ์ˆ˜ํ–‰๋˜๊ธฐ ์ „์— ์ด์ „ effect๋Š” ์ •๋ฆฌ๋œ๋‹ค.

        useEffect(() => {
            console.log("effect");
            console.log({
                name, nickName
            })
            return () =>{
                console.log('cleanUp');
                console.log(name);
            }
        },[])
    • ์ •๋ฆฌ ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ๋Š” ์—…๋ฐ์ดํŠธ๋˜๊ธฐ ์ง์ „ ๊ฐ’์„ ๋ณด์—ฌ์ค€๋‹ค.

    ๐ŸŒˆ useContext

    • ๐Ÿ“Œ React context ์ฐธ๊ณ 

      const value = useContext(MyContext);
    • context ๊ฐ์ฒด(React.createContext์—์„œ ๋ฐ˜ํ™˜๋œ ๊ฐ’)๋ฅผ ๋ฐ›์•„ ๊ทธ context์˜ ํ˜„์žฌ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

    • ์ปดํฌ๋„ŒํŠธ์—์„œ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด <MyContext.Provider>๊ฐ€ ๊ฐฑ์‹ ๋˜๋ฉด ์ด Hook์€ ๊ทธ MyContext.Provider์—๊ฒŒ ์ „๋‹ฌ๋œ ๊ฐ€์žฅ ์ตœ์‹ ์˜ context value๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ Œ๋”๋Ÿฌ๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•œ๋‹ค.

    • useContext๋กœ ์ „๋‹ฌ๋œ ์ธ์ž๋Š” context ๊ฐ์ฒด ๊ทธ ์ž์ฒด์ด์–ด์•ผ ํ•œ๋‹ค.

    • useContext๋ฅผ ํ˜ธ์ถœํ•œ ์ปดํฌ๋„ŒํŠธ๋Š” context ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜๋ฉด ํ•ญ์ƒ ๋ฆฌ๋ Œ๋”๋ง ๋œ๋‹ค. ๋งŒ์•ฝ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ฆฌ๋ Œ๋”๋ง ํ•˜๋Š” ๊ฒƒ์— ๋ณต์žกํ•ด์ง„๋‹ค๋ฉด, ๋ฉ”๋ชจ์ด์ œ์ด์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค.

        const themes = {
          light: {
            foreground: "#000000",
            background: "#eeeeee"
          },
          dark: {
            foreground: "#ffffff",
            background: "#222222"
          }
        };
      
        const ThemeContext = React.createContext(themes.light);
      
        function App() {
          return (
          // Provider๋กœ prop์„ ๋ฐ›์•„์„œ ์ด ๊ฐ’์„ ํ•˜์œ„์— ์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ์—๊ฒŒ ์ „๋‹ฌํ•œ๋‹ค. (context์˜ ๋ณ€ํ™”๋ฅผ ์•Œ๋ฆฐ๋‹ค.)
            <ThemeContext.Provider value={themes.dark}>
              <Toolbar />
            </ThemeContext.Provider>
          );
        }
        function Toolbar(props) {
          return (
            <div>
              <ThemedButton />
            </div>
          );
        }
        function ThemedButton() {
          const theme = useContext(ThemeContext);
          return (
            <button style={{ background: theme.background, color: theme.foreground }}>test</button>
          );
        }

    ๐ŸŒˆ useReducer

    const [state, dispatch] = useReducer(reducer, initialArg, init);
    • useState์˜ ๋Œ€์ฒด ํ•จ์ˆ˜๋กœ (state, action) => newState์˜ ํ˜•ํƒœ๋กœ reducer๋ฅผ ๋ฐ›๊ณ  dispatch ๋ฉ”์„œ๋“œ์™€ ์ง์˜ ํ˜•ํƒœ๋กœ ํ˜„์žฌ state๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

    • ๋ฆฌ๋“€์„œ๋Š” ํ˜„์žฌ ์ƒํƒœ, ๊ทธ๋ฆฌ๊ณ  ์—…๋ฐ์ดํŠธ๋ฅผ ์œ„ํ•ด ํ•„์š”ํ•œ ์ •๋ณด๋ฅผ ๋‹ด์€ ์•ก์…˜ ๊ฐ’์„ ์ „๋‹ฌ๋ฐ›์•„ ์ƒˆ๋กœ์šด ์ƒํƒœ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค.

    • ๋ฆฌ๋“€์„œ ํ•จ์ˆ˜์—์„œ ์ƒˆ๋กœ์šด ์ƒํƒœ๋ฅผ ๋งŒ๋“ค ๋•Œ๋Š” ๋ถˆ๋ณ€์„ฑ์„ ์ง€์ผœ์•ผ ํ•œ๋‹ค.

    • useReducer๋Š” ์ฝœ๋ฐฑ ๋Œ€์‹  dispatch๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์—…๋ฐ์ดํŠธ๋ฅผ ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์˜ ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค.

        const initialState = {value : 0};
        function reducer(state,action){
          switch (action.type){
              case 'INCREMENT':
                  return {value : state.value + 1};
              case 'DECREMENT':
                  return {value : state.value - 1};
              default :
              //์•„๋ฌด๊ฒƒ๋„ ํ•ด๋‹น๋˜์ง€ ์•Š์„ ๋•Œ ๊ธฐ์กด ์ƒํƒœ ๋ฐ˜ํ™˜
                  return state;
          }
        }
        const Counter = () => {
            // useReducer(๋ฆฌ๋“€์„œ ํ•จ์ˆ˜, ์ดˆ๊ธฐ๊ฐ’)
          const [state, dispatch] = useReducer(reducer,initialState);
          return (
              <div>
                  <p>
                      ํ˜„์žฌ ์นด์šดํ„ฐ ๊ฐ’์€ <b>{state.value}</b>์ž…๋‹ˆ๋‹ค.
                  </p>
                  <button onClick={() => dispatch({type : 'INCREMENT'})}>+1</button>
                  <button onClick={() => dispatch({type : 'DECREMENT'})}>-1</button>
      
              </div>
          );
        };
    • state๊ฐ’๊ณผ dispatch ํ•จ์ˆ˜๋ฅผ ๋ฐ›์•„์˜ค๋Š”๋ฐ state๋Š” ํ˜„์žฌ ๊ฐ€๋ฆฌํ‚ค๊ณ  ์žˆ๋Š” ์ƒํƒœ์ด๊ณ , dispatch๋Š” ์•ก์…˜์„ ๋ฐœ์ƒ ํ‚ค๊ธฐ๋Š” ํ•จ์ˆ˜์ด๋‹ค.

    • useReducer๋ฅผ ์‚ฌ์šฉํ–ˆ์„ ๋•Œ ๊ฐ€์žฅ ํฐ ์žฅ์ ์€ ์ปดํฌ๋„ŒํŠธ ์—…๋ฐ์ดํŠธ ๋กœ์ง์„ ์ปดํฌ๋„ŒํŠธ ๋ฐ”๊นฅ์œผ๋กœ ๋นผ๋‚ผ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ด๋‹ค.

    ๐Ÿ”ธ ์ดˆ๊ธฐํ™” ์ง€์—ฐ

    • ์ดˆ๊ธฐํ™” state๋ฅผ ์ง€์—ฐ์‹œ์ผœ์„œ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

    • useReducer(๋ฆฌ๋“€์„œ ํ•จ์ˆ˜, ์ดˆ๊ธฐ๊ฐ’, init ํ•จ์ˆ˜) ์„ธ ๋ฒˆ์งธ ์ธ์ž๋กœ ์ „๋‹ฌํ•œ๋‹ค.

    • ์˜ˆ๋ฅผ ๋“ค์–ด ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ์— state๋ฅผ ์žฌ์„ค์ •์‹œํ‚จ๋‹ค.

      function init(initialCount) {
      return {count: initialCount};
      }
      
      function reducer(state, action) {
      switch (action.type) {
        case 'INCREMENT':
          return {count: state.count + 1};
        case 'DECREMENT':
          return {count: state.count - 1};
        case 'reset':
          return init(action.payload);
        default:
             state;
      }
      }
      
      function Counter({initialCount}) {
      const [state, dispatch] = useReducer(reducer, initialCount, init);
      return (
        <>
          Count: {state.count}
          <button
            onClick={() => dispatch({type: 'reset', payload: initialCount})}>
            Reset
          </button>
          <button onClick={() => dispatch({type: 'DECREMENT'})}>-</button>
          <button onClick={() => dispatch({type: 'INCREMENT'})}>+</button>
        </>
      );
      }

    ๐ŸŒˆ useMemo

    • useMemo๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์—์„œ ๋ฐœ์ƒํ•˜๋Š” ์—ฐ์‚ฐ์„ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค.

    • ๋ฉ”๋ชจ์ด์ œ์ด์…˜๋œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

    • ๋ Œ๋”๋ง ํ•˜๋Š” ๊ณผ์ •์—์„œ ํŠน์ • ๊ฐ’์ด ๋ฐ”๋€Œ์—ˆ์„ ๋•Œ๋งŒ ์—ฐ์‚ฐ์„ ์‹คํ–‰ํ•˜๊ณ , ์›ํ•˜๋Š” ๊ฐ’์ด ๋ฐ”๋€Œ์ง€ ์•Š์•˜๋‹ค๋ฉด ์ด์ „์— ์—ฐ์‚ฐํ–ˆ๋˜ ๊ฒฐ๊ณผ๋ฅผ ๋‹ค์‹œ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

    • useMemo๋กœ ์ „๋‹ฌ๋œ ํ•จ์ˆ˜๋Š” ๋ Œ๋”๋ง ์ค‘์— ์‹คํ–‰๋œ๋‹ค. ๋•Œ๋ฌธ์— ๋ Œ๋”๋ง ์ค‘์— ์‹คํ–‰๋˜์ง€ ์•Š๋Š” ๊ฒƒ์€ ์‚ฌ์šฉํ•˜๋ฉด ์•ˆ ๋œ๋‹ค.

        const getAverage = numbers => {
            console.log("ํ‰๊ท ๊ฐ’ ๊ณ„์‚ฐ");
            if(numbers.length === 0)return 0;
            const sum = numbers.reduce((a,b) => a+b);
            return sum / numbers.length;
        }
        // ์ƒ๋žต..
        const avg = useMemo(() => getAverage(list), [list]); // list ๊ฐ’์ด ๋ณ€๊ฒฝ๋ ๋•Œ๋งŒ ์‹คํ–‰
        // ์ƒ๋žต..

    ๐ŸŒˆ useCallback

    • useMemo์™€ ๋น„์Šทํ•˜๊ณ  ๋ Œ๋”๋ง ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•ด์•ผ ํ•˜๋Š” ์ƒํ™ฉ์—์„œ ์‚ฌ์šฉ๋œ๋‹ค.

    • ๋ฉ”๋ชจ์ด์ œ์ด์…˜๋œ ์ฝœ๋ฐฑ์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

    • ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ํ•จ์ˆ˜๋ฅผ ํ•„์š”ํ•  ๋•Œ๋งŒ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

    • useCallback(fn, deps)์€ useMemo(() => fn, deps)์™€ ๊ฐ™๋‹ค.

       const onChange = useCallback(e => {
         setNumber(e.target.value);
       },[]); //์ฒ˜์Œ ๋žœ๋”๋ง๋  ๋•Œ๋งŒ ํ•จ์ˆ˜ ์ƒ์„ฑ
       const onInsert = useCallback(e => {
         const nextList = list.concat(parseInt(number));
         setList(nextList);
         setNumber('');
       },[number,list]); //number, list ๊ฐ€ ๋ฐ”๋€Œ์—ˆ์„ ๋–„๋งŒ ํ•จ์ˆ˜ ์ƒ์„ฑ
    • useCallback์˜ ์ฒซ ๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ์—๋Š” ์ƒ์„ฑํ•˜๊ณ  ์‹ถ์€ ํ•จ์ˆ˜๋ฅผ ๋„ฃ๊ณ , ๋‘ ๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ์—๋Š” ์–ด๋–ค ๊ฐ’์ด ๋ฐ”๋€Œ์—ˆ์„ ๋•Œ ํ•จ์ˆ˜๋ฅผ ์ƒˆ๋กœ ์ƒ์„ฑํ•ด์•ผ ํ•˜๋Š”์ง€๋ฅผ ๋ช…์‹œํ•˜๋Š” ๋ฐฐ์—ด์„ ๋„ฃ๋Š”๋‹ค.

    • ๋นˆ ๋ฐฐ์—ด์„ ๋„ฃ๊ฒŒ ๋˜๋ฉด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋ง ๋  ๋•Œ ๋‹จ ํ•œ ๋ฒˆ๋งŒ ํ•จ์ˆ˜๊ฐ€ ์ƒ์„ฑ๋˜๊ณ , ๋ฐฐ์—ด ์•ˆ์— ๊ฐ’์„ ๋„ฃ๊ฒŒ ๋˜๋ฉด ๋‚ด์šฉ์ผ ๋ฐ”๋€Œ๊ฑฐ๋‚˜ ์ƒˆ๋กœ์šด ํ•ญ๋ชฉ์ด ์ถ”๊ฐ€๋  ๋•Œ๋งˆ๋‹ค ํ•จ์ˆ˜๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค.

    ๐ŸŒˆ useRef

    • ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ์—์„œ ref๋ฅผ ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค€๋‹ค.

      function TextInputWithFocusButton() {
        const inputEl = useRef(null); //ref ๊ฐ’ ๊ธฐ๋ณธ๊ฐ’ ์„ค์ •
        const onButtonClick = () => {
          inputEl.current.focus(); // ๋“ฑ๋ก๋ฒ„ํŠผ ๋ˆ„๋ฅธ๋’ค input ํƒœ๊ทธ focus
        };
        return (
          <>
            <input ref={inputEl} type="text" />
            <button onClick={onButtonClick}>ํด๋ฆญ</button>
          </>
        );
      }
    • useRef๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ref๋ฅผ ์„ค์ •ํ•˜๋ฉด useRef๋ฅผ ํ†ตํ•ด ๋งŒ๋“  ๊ฐ์ฒด ์•ˆ์˜ current ๊ฐ’์ด ์‹ค์ œ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.

    • ref ์•ˆ์˜ ๊ฐ’์ด ๋ฐ”๋€Œ์–ด๋„ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋ง ๋˜์ง€ ์•Š๋Š”๋‹ค.(๋ Œ๋”๋ง๊ณผ ๊ด€๋ จ๋˜์ง€ ์•Š์€ ๊ฐ’์„ ๊ด€๋ฆฌํ•  ๋•Œ๋งŒ ์‚ฌ์šฉ)

    ๐ŸŒˆ useImperativeHandle

    useImperativeHandle(ref, createHandle, [deps])
    • useImperativeHandle์€ ref๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์— ๋…ธ์ถœ๋˜๋Š” ์ธ์Šคํ„ด์Šค ๊ฐ’์„ ์‚ฌ์šฉ์ž ํ™”ํ•œ๋‹ค.
    • useImperativeHandle๋Š” forwardRef์™€ ๊ฐ™์ด ์‚ฌ์šฉํ•œ๋‹ค.
      function FancyInput(props, ref) {
        const inputRef = useRef();
        useImperativeHandle(ref, () => ({
          focus: () => {
            inputRef.current.focus();
          }
        }));
        return <input ref={inputRef} ... />;
      }
      FancyInput = forwardRef(FancyInput);
    • <FancyInput ref={inputRef} />๋ฅผ ๋ Œ๋”๋ง ํ•œ ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๋Š” inputRef.current.focus();๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค.

    ๐ŸŒˆ useLayoutEffect

    • ์ด ํ•จ์ˆ˜๋Š” ๋ชจ๋“  DOM ๋ณ€๊ฒฝ ํ›„์— ๋™๊ธฐ์ ์œผ๋กœ ๋ฐœ์ƒํ•˜๊ณ  DOM์—์„œ ๋ ˆ์ด์•„์›ƒ์„ ์ฝ๊ณ  ๋™๊ธฐ์ ์œผ๋กœ ๋ฆฌ๋ Œ๋”๋งํ•˜๋Š” ๊ฒฝ์šฐ์— ์‚ฌ์šฉํ•œ๋‹ค.
    • useLayoutEffect์˜ ๋‚ด๋ถ€์— ์˜ˆ์ •๋œ ๊ฐฑ์‹ ์€ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ํ™”๋ฉด์„ ๊ทธ๋ฆฌ๊ธฐ ์ด์ „ ์‹œ์ ์— ๋™๊ธฐ์ ์œผ๋กœ ์ˆ˜ํ–‰๋œ๋‹ค.
    • useLayoutEffect๋Š” componentDidMount๋‚˜ componentDidUpdate์™€ ๋™์ผํ•œ ๋‹จ๊ณ„๋ฅผ ์‹คํ–‰ํ•˜๊ธด ํ•˜์ง€๋งŒ ๋จผ์ € useEffect๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ๋ฌธ์ œ๊ฐ€ ์žˆ์œผ๋ฉด useLayoutEffect์„ ์‚ฌ์šฉํ•ด๋ณธ๋‹ค.

    ๐ŸŒˆ useDebugValue

    • useDebugValue๋Š” React ๊ฐœ๋ฐœ์ž ๋„๊ตฌ์—์„œ ์‚ฌ์šฉ์ž Hook ๋ ˆ์ด๋ธ”์„ ํ‘œ์‹œํ•˜๋Š” ๋ฐ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

        function useFriendStatus(friendID) {
          const [isOnline, setIsOnline] = useState(null);
          useDebugValue(isOnline ? 'Online' : 'Offline');
      
          return isOnline;
        }

    ๐ŸŒˆ ๋‹ค๋ฅธ Hooks

     

    Hooks API Reference – React

    A JavaScript library for building user interfaces

    ko.reactjs.org

     

    ๋Œ“๊ธ€

Designed by Seungmin Sa.