1. ホーム
  2. reactjs

[解決済み] MakeStyles を使用してコンポーネントのスタイルを設定し、マテリアル UI のライフサイクル メソッドを維持するにはどうすればよいですか?

2022-05-09 14:06:08

質問

を使用しようとすると、以下のエラーが発生します。 makeStyles() を、ライフサイクル・メソッドを持つコンポーネントで使用することができます。

無効なフック呼び出しです。フックは、関数コンポーネントの本体内部でのみ呼び出すことができます。これは、次のいずれかの理由で発生する可能性があります。

  1. Reactとレンダラー(React DOMなど)のバージョンが不一致である可能性があります。
  2. フックのルールを破っている可能性があります。
  3. 同じアプリに複数のReactのコピーを持っている可能性があります。

以下は、このエラーを発生させるコードの小さな例です。他の例でも同様に、子アイテムにクラスを割り当てています。MUIのドキュメントには、他の方法を示すものは見当たりません。 makeStyles で、ライフサイクルメソッドを使用する機能があります。

    import React, { Component } from 'react';
    import { Redirect } from 'react-router-dom';

    import { Container, makeStyles } from '@material-ui/core';

    import LogoButtonCard from '../molecules/Cards/LogoButtonCard';

    const useStyles = makeStyles(theme => ({
      root: {
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
      },
    }));

    const classes = useStyles();

    class Welcome extends Component {
      render() {
        if (this.props.auth.isAuthenticated()) {
          return <Redirect to="/" />;
        }
        return (
          <Container maxWidth={false} className={classes.root}>
            <LogoButtonCard
              buttonText="Enter"
              headerText="Welcome to PlatformX"
              buttonAction={this.props.auth.login}
            />
          </Container>
        );
      }
    }

    export default Welcome;

どのように解決するのですか?

結局、クラスコンポーネントをやめて、ファンクショナルコンポーネントを作りました。 使って useEffect() から ライフサイクルメソッド用フックAPI . これにより、今まで通り makeStyles() ライフサイクルメソッドによる 高次のコンポーネントを作るという複雑な作業を加えることなく . どちらがよりシンプルかというと

import React, { useEffect, useState } from 'react';
import axios from 'axios';
import { Redirect } from 'react-router-dom';

import { Container, makeStyles } from '@material-ui/core';

import LogoButtonCard from '../molecules/Cards/LogoButtonCard';

const useStyles = makeStyles(theme => ({
  root: {
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    margin: theme.spacing(1)
  },
  highlight: {
    backgroundColor: 'red',
  }
}));

// Highlight is a bool
const Welcome = ({highlight}) => { 
  const [userName, setUserName] = useState('');
  const [isAuthenticated, setIsAuthenticated] = useState(true);
  const classes = useStyles();

  useEffect(() => {
    axios.get('example.com/api/username/12')
         .then(res => setUserName(res.userName));
  }, []);

  if (!isAuthenticated()) {
    return <Redirect to="/" />;
  }
  return (
    <Container maxWidth={false} className={highlight ? classes.highlight : classes.root}>
      <LogoButtonCard
        buttonText="Enter"
        headerText={isAuthenticated && `Welcome, ${userName}`}
        buttonAction={login}
      />
   </Container>
   );
  }
}

export default Welcome;