为什么我在React中收到“无效的挂机呼叫”错误?

时间:2020-04-24 14:07:52

标签: javascript reactjs ecmascript-6

我对React还是很陌生,目前正在努力将功能组件更改为类,但是我收到以下错误:

错误:无效的挂钩调用。挂钩只能在功能组件的主体内部调用。

这似乎与第11行有关:

const { choices, setChoices } = useContext(ChoicesContext);

任何帮助都非常有用。

import React, { useContext } from "react";
import { Link } from "react-router-dom";
import CategoryData from "./data/CategoryData";
import { ChoicesContext } from "../context/ChoicesProvider";
import { ReactComponent as Logo } from '../images/logo.svg';
import { ReactComponent as WaterTechLogo } from '../images/water-tech-logo.svg';

class Applications extends React.Component {

  render() {
    const { choices, setChoices } = useContext(ChoicesContext);

    return (
      <>
        <Link to="/">
          <Logo className="Logo" />
        </Link>
        <WaterTechLogo className="WaterTechLogo" />

        <div className="pageLinks">
          <div className="breadcrumb">Applications</div>
          <div className="backBtn"></div>
        </div>

        <div className="applications wrapper d-md-flex">
          <aside>
            <h2>Select an<br />Application</h2>
          </aside>

          <main>
            <div id="applicationsList">
              {CategoryData.map((cat, i) => (
                <div key={i} className="application">
                  <Link
                    onClick={() => setChoices({ ...choices, category: cat.name })}
                    to={{
                      pathname: "/waterType",
                      name: cat.name,
                    }}
                  >
                    <img src={cat.imageURL} alt={cat.name} />
                    <h4 className="appTitle">{cat.name}</h4>
                  </Link>
                </div>
              ))}
            </div>
          </main>
        </div>
      </>
    );
  }
}

export default Applications;

2 个答案:

答案 0 :(得分:2)

该错误清楚地表明,挂钩只能在功能组件内部调用。但是,您的Applications组件是一个类组件,您正在尝试在其中使用useContext。

将其转换为类似功能的组件

const Applications = () =>  {
    const { choices, setChoices } = useContext(ChoicesContext);

    return (
      <>
        <Link to="/">
          <Logo className="Logo" />
        </Link>
        <WaterTechLogo className="WaterTechLogo" />

        <div className="pageLinks">
          <div className="breadcrumb">Applications</div>
          <div className="backBtn"></div>
        </div>

        <div className="applications wrapper d-md-flex">
          <aside>
            <h2>Select an<br />Application</h2>
          </aside>

          <main>
            <div id="applicationsList">
              {CategoryData.map((cat, i) => (
                <div key={i} className="application">
                  <Link
                    onClick={() => setChoices({ ...choices, category: cat.name })}
                    to={{
                      pathname: "/waterType",
                      name: cat.name,
                    }}
                  >
                    <img src={cat.imageURL} alt={cat.name} />
                    <h4 className="appTitle">{cat.name}</h4>
                  </Link>
                </div>
              ))}
            </div>
          </main>
        </div>
      </>
    );
}

export default Applications;

另一种解决方案是通过定义静态contextType属性,像在类组件中一样使用Context

class Applications extends React.Component {
  static contextType = ChoicesContext;
  render() {
    const { choices, setChoices } = this.context;

    return (
      <>
        <Link to="/">
          <Logo className="Logo" />
        </Link>
        <WaterTechLogo className="WaterTechLogo" />

        <div className="pageLinks">
          <div className="breadcrumb">Applications</div>
          <div className="backBtn"></div>
        </div>

        <div className="applications wrapper d-md-flex">
          <aside>
            <h2>Select an<br />Application</h2>
          </aside>

          <main>
            <div id="applicationsList">
              {CategoryData.map((cat, i) => (
                <div key={i} className="application">
                  <Link
                    onClick={() => setChoices({ ...choices, category: cat.name })}
                    to={{
                      pathname: "/waterType",
                      name: cat.name,
                    }}
                  >
                    <img src={cat.imageURL} alt={cat.name} />
                    <h4 className="appTitle">{cat.name}</h4>
                  </Link>
                </div>
              ))}
            </div>
          </main>
        </div>
      </>
    );
  }
}

export default Applications;

答案 1 :(得分:0)

您不能在类组件内部使用钩子。仅在功能组件中。