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

我是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;
评论
  • ~那么美
    ~那么美 回复

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

  • inisi
    inisi 回复

    该错误明确指出,挂钩只能在功能组件内部调用。但是,您的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;