不变违规:只能在函数组件的主体内部调用钩子

时间:2018-12-04 12:05:44

标签: javascript reactjs react-hooks

嘿,我知道这个问题已经被问过几次了,但是那里发布的解决方案似乎都没有真正解决我的问题。那么有人可以看看并帮助我确定错误在哪里吗?

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

预先感谢

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;

3 个答案:

答案 0 :(得分:2)

如果您回想类组件版本,您的代码正在this.setState中调用render(),这将触发另一个渲染,然后再次调用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>

答案 1 :(得分:1)

调用setHeading(“ Brussel”)将导致一次又一次的重新渲染,从而导致无限循环,以防止您需要一个事件来将标题从“ Heading”更改为“ Brussels”。 下面的代码可能会帮助您

const Text = () => {
const initialState= 'Heading'.toUpperCase();
const [heading, setHeading] = useState(initialState);  
return (
 <header>
    <h1>
    {heading}
    <button onClick= {() =>{setHeading("Brussel")}}>ChangeName</button>
    </h1>
    </header>
);
};

答案 2 :(得分:0)

我在某个项目中升级了我的 react 版本,所以我可以使用钩子,直到那时我遇到了同样的问题,并且根据文档,错误是由于 react 和 react-dom 的版本不匹配而发生的。升级 react-dom 适用于我的情况。

https://reactjs.org/warnings/invalid-hook-call-warning.html