๐Ÿ’ป๐Ÿ’€/๊ฐœ๋ฐœ

[React] Invalid Hook Call Warning(ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ์—์„œ Hook ์‚ฌ์šฉํ•˜๊ธฐ)

db2 2021. 9. 19. 10:32

์—๋Ÿฌ

๋ฆฌ์•กํŠธ ๊ณต์‹ ํ™ˆํŽ˜์ด์ง€์—์„œ Invalid Hook Call Warning๋ผ๋Š” ํƒ€์ดํ‹€๋กœ ์ด ์ด์Šˆ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์•„์ฃผ ์นœ์ ˆํ•˜๊ฒŒ ์ œ๊ณตํ•˜๊ณ  ์žˆ๋‹ค.

Hooks can only be called inside the body of a function component.

There are three common reasons you might be seeing it:

1. You might have mismatching versions of React and React DOM.
2. You might be breaking the Rules of Hooks.
3. You might have more than one copy of React in the same app.

์›์ธ

์˜†์— ๊ณ„์‹  ๋””๋ธ”๋ฆฌ์…”๋ถ„์ด ๋„์›€์„ ์š”์ฒญํ–ˆ๋˜ ์—๋Ÿฌ์ด๋‹ค. ๋ฐ˜์‘ํ˜• ํผ๋ธ”๋ฆฌ์‹ฑ์„ ์œ„ํ•ด use-media๋ผ๋Š” ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋‹ค๊ฐ€ ๋ฐœ์ƒํ–ˆ๋Š”๋ฐ, ์›์ธ์€ 2๋ฒˆ 'You might be breaking the Rules of Hooks' ์— ํ•ด๋‹นํ•˜๋Š” ๊ฒƒ์ด์—ˆ๋‹ค. ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ์—์„œ๋Š” Hook์„ ํ˜ธ์ถœํ•˜๋ฉด ์•ˆ๋˜๋Š”๋ฐ ๊ทธ ๊ทœ์น™์„ ์–ด๊ธฐ๊ณ  ์žˆ์—ˆ๋˜ ๊ฒƒ์ด๋‹ค.

์™„์ „ํžˆ ๋‹ค๋ฅธ ํŒ€์˜ ์ฝ”๋“œ๋ผ ์ •ํ™•ํ•˜๊ฒŒ ๊ธฐ์–ต์ด ๋‚˜์งˆ ์•Š์•„ ๋น„์Šทํ•˜๊ฒŒ ๊ตฌ์กฐ๋งŒ ๊ตฌํ˜„ํ–ˆ๋‹ค.

import React from 'react'; 
import { connect } from 'react-redux';
import useMedia from 'use-media';

class DashboardTitle extends React.Component {
    ์–ด๋–ค๋ฉค๋ฒ„ํ•จ์ˆ˜ () {
        return {
            ...
            widgets: function () {
                const isTabletPC = useMedia({ maxWidth: '800px' });
                // isTabletPC ๊ฐ€ true์ด๋ฉด a๋ฅผ ๋ Œ๋”๋งํ•˜๊ณ  ์•„๋‹ˆ๋ฉด b๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ์ฝ”๋“œ
            }
        }
    }

    render () {
        return <์–ด๋–ค์ปดํฌ๋„ŒํŠธ> { ์–ด๋–ค๋ฉค๋ฒ„ํ•จ์ˆ˜.widgets() } </์–ด๋–ค์ปดํฌ๋„ŒํŠธ>
    }
}

const mapStateToProps = (state) => {};

const mapDispatchToProps = (dispatch) => {};

export default connect(mapStateToProps, mapDispatchToProps)(DashboardTitle);

ํ•ด๊ฒฐ

์ฒ˜์Œ์—๋Š” use-media๊ฐ€ ์ž์ฒด์ ์œผ๋กœ ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•˜๋Š”์ง€ ์ฐพ์•„๋ณด์•˜์œผ๋‚˜ ๋ฐœ๊ฒฌํ•˜์ง€ ๋ชปํ–ˆ๋‹ค.

๊ทธ๋ž˜์„œ ๋‹ค์‹œ ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ์—์„œ ํ›…์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋Š”์ง€ ๊ฒ€์ƒ‰ํ–ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ •๋‹ต์€ ๋ฐ”๋กœ How can I use React hooks in React classic class component?์— ์žˆ์—ˆ๋‹ค. HOC๋ฅผ ํ†ตํ•ด ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ์— Hook์„ ํ˜ธ์ถœํ•ด ๋ฆฌํ„ด๋ฐ›์€ ๊ฒฐ๊ณผ๋ฅผ props๋กœ ์ „๋‹ฌํ•ด์คŒ์œผ๋กœ์จ, ๊ฒฐ๊ณผ์ ์œผ๋กœ๋Š” ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ ์•ˆ์—์„œ Hook์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฉด์„œ๋„ ์‚ฌ์šฉํ•œ ๊ฒƒ๊ณผ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.

์˜ˆ๋กœ withHook์ด๋ผ๋Š” HOC ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค. ์ด ํ•จ์ˆ˜๋Š” MyComponent์— Hook์„ ํ˜ธ์ถœํ•ด ์–ป์€ ๊ฒฐ๊ณผ isTabletPC๋ฅผ props๋กœ ์ถ”๊ฐ€ํ•œ ๋’ค ๋ฐ˜ํ™˜ํ•œ๋‹ค. export ํ•  ๋•Œ withHook ํ•จ์ˆ˜์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ isTabletPC๋ฅผ ์‚ฌ์šฉํ•˜๊ณ ์žํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋„˜๊ฒจ์ค€๋‹ค๋ฉด, ๊ทธ ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์—์„œ this.props.isTabletPC๋กœ ์ ‘๊ทผํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

import React from 'react'; 
import { connect } from 'react-redux';
import useMedia from 'use-media';

function withHook (MyComponent) {
  return function WrappedComponent (props) {
      const isTabletPC = useMedia({ maxWidth: '800px' });
    return <MyComponent {...props} isTabletPC={isTabletPC} />;
  }
}

class DashboardTitle extends React.Component {
    // ... 

    ์–ด๋–ค๋ฉค๋ฒ„ํ•จ์ˆ˜ () {
        return {
            widgets: function () {
                // this.props.isTabletPC ๋กœ ์ ‘๊ทผ
            }
        }
    }

    render () {
        return <์–ด๋–ค์ปดํฌ๋„ŒํŠธ> { ์–ด๋–ค๋ฉค๋ฒ„ํ•จ์ˆ˜.widgets() } </์–ด๋–ค์ปดํฌ๋„ŒํŠธ>
    }
}

const mapStateToProps = (state) => {};

const mapDispatchToProps = (dispatch) => {};

export default connect(mapStateToProps, mapDispatchToProps)(withHook(DashboardTitle));

โž•

๋‚˜๋Š” ๋ฆฌ์•กํŠธ๋ฅผ ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ๋กœ ๋ฐฐ์šฐ๊ณ  ๊ทธ ์ดํ›„์—๋„ ์ญ‰ ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ๋งŒ ์“ฐ๊ณ  ์žˆ๋‹ค. ๊ทธ๋ž˜์„œ ๊ตฌ๊ธ€๋ง์œผ๋กœ ๋ฌธ์ œ๋Š” ํ•ด๊ฒฐํ–ˆ์ง€๋งŒ ์ •ํ™•ํžˆ ์ด ์ƒํ™ฉ์—์„œ ์ด๋ ‡๊ฒŒ ํ•ด๊ฒฐํ•˜๋Š” ๊ฒƒ์ด ์ตœ์„ ์ธ๊ฑด์ง€ ํŒ๋‹จํ•˜๊ธฐ๊ฐ€ ํž˜๋“ค์—ˆ๋‹ค. ์• ์ดˆ์— ํ˜ธํ™˜๋˜์ง€ ์•Š๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ์ง€์–‘ํ•ด์•ผํ•˜๋Š” ๊ฑด์ง€(๋™์ผ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋ฉด์„œ ํด๋ž˜์Šค์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋‹ค๋ฅธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ฐพ๋Š” ๋“ฑ), ์•„๋‹ˆ๋ฉด ์ด๋ ‡๊ฒŒ HOC๋ฅผ ๋งŒ๋“ค์–ด์„œ ์‚ฌ์šฉํ•˜๋ฉด ๋˜๋Š” ๊ฑด์ง€์— ๋Œ€ํ•œ ์˜๋ฌธ์ ์ด ๋‚จ๋Š”๋‹ค.