首页 > 解决方案 > Invariant Violation:Hooks 只能在函数组件的主体内部调用

问题描述

TL;DR:我正在尝试使用新的react-hooksapi,但在调用钩子时我不断收到 Invariant Violation 错误setState,但它一直失败。

import React, { useState } from 'react';

// type State = {
//   heading: string;
// }

const Text = () => {
  const initialState = 'Heading'.toUpperCase();

  const [heading, setHeading] = useState(initialState);

  return (
    <header>
      <h1>
        {setHeading('Brussels')};
        {heading}
      </h1>
    </header>
  );
};

export default Text;

标签: javascriptreactjsreact-hooks

解决方案


如果您回想类组件版本,您的代码正在调用this.setStaterender()这将触发另一个渲染,然后this.setState再次调用,循环重复,您将收到错误:

未捕获的错误:重新渲染过多。React 限制了渲染的数量以防止无限循环。

您不会this.setState直接在您的渲染方法中调用,也不应该使用钩子来调用。

目前尚不清楚您要在这里实现什么,但我认为您想要的是只设置一次名称,您将在 中执行此操作componentDidMount,您可以使用useEffect钩子来实现这一点。

或者,如果您希望“布鲁塞尔”成为初始状态,请将其作为值传递给useState().

const {useState, useEffect} = React;

const Text = () => {
  const initialState = 'Heading'.toUpperCase();
  const [heading, setHeading] = useState(initialState);
  useEffect(() => {
    setHeading('Brussels');
  }, []); // Pass in empty array to simulate componentDidMount.
  
  return (
    <header>
      <h1>
        {heading}
      </h1>
    </header>
  );
};

ReactDOM.render(<Text />, document.querySelector('#app'));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>
<div id="app"></div>


推荐阅读