不变违规:钩子只能在函数组件的内部调用
Invariant Violation: Hooks can only be called inside the body of a function component
TL;DR: 我正在尝试使用新的 react-hooks
api,但在调用 setState
hook,但是总是失败。
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;
调用 setHeading("Brussel") 将导致一次又一次地重新渲染,这又会导致无限循环,以防止您需要一个事件来将 header 从 [=14= 更改为] 到 "Brussels"。
以下代码可能对您有所帮助
const Text = () => {
const initialState= 'Heading'.toUpperCase();
const [heading, setHeading] = useState(initialState);
return (
<header>
<h1>
{heading}
<button onClick= {() =>{setHeading("Brussel")}}>ChangeName</button>
</h1>
</header>
);
};
如果你回想在 class 组件版本中,你的代码在 render()
中调用 this.setState
这将触发另一个渲染,并再次调用 this.setState
,循环重复,你会得到错误:
Uncaught Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.
您不会直接在渲染方法中调用 this.setState
,也不应该使用挂钩来调用。
不清楚你在这里想要实现什么,但我认为你想要的是只设置一次名称,你会在 componentDidMount
中这样做,你可以使用 useEffect
钩子来实现。
或者如果你想让"Brussels"成为初始状态,将它作为值传递给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>
我在某个项目中升级了我的反应版本,所以我可以使用钩子,直到那时我遇到了同样的问题,并且根据文档,由于反应版本和反应-dom 不匹配而发生错误。升级 react-dom 适用于我的情况。
TL;DR: 我正在尝试使用新的 react-hooks
api,但在调用 setState
hook,但是总是失败。
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;
调用 setHeading("Brussel") 将导致一次又一次地重新渲染,这又会导致无限循环,以防止您需要一个事件来将 header 从 [=14= 更改为] 到 "Brussels"。 以下代码可能对您有所帮助
const Text = () => {
const initialState= 'Heading'.toUpperCase();
const [heading, setHeading] = useState(initialState);
return (
<header>
<h1>
{heading}
<button onClick= {() =>{setHeading("Brussel")}}>ChangeName</button>
</h1>
</header>
);
};
如果你回想在 class 组件版本中,你的代码在 render()
中调用 this.setState
这将触发另一个渲染,并再次调用 this.setState
,循环重复,你会得到错误:
Uncaught Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.
您不会直接在渲染方法中调用 this.setState
,也不应该使用挂钩来调用。
不清楚你在这里想要实现什么,但我认为你想要的是只设置一次名称,你会在 componentDidMount
中这样做,你可以使用 useEffect
钩子来实现。
或者如果你想让"Brussels"成为初始状态,将它作为值传递给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>
我在某个项目中升级了我的反应版本,所以我可以使用钩子,直到那时我遇到了同样的问题,并且根据文档,由于反应版本和反应-dom 不匹配而发生错误。升级 react-dom 适用于我的情况。