Reputation: 2399
TL;DR: I'm trying to use the new react-hooks
api, but I keep getting an Invariant Violation error when calling the setState
hook, but it keeps failing.
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;
Upvotes: 6
Views: 20091
Reputation: 653
I upgraded my react version in a certain project so I can use hooks until then I had the same issue and based on the docs the error occurs for mismatching the version of react and react-dom. Upgrading the react-dom works for in my case.
https://reactjs.org/warnings/invalid-hook-call-warning.html
Upvotes: 0
Reputation: 53169
If you think back in the class component version, your code is calling this.setState
in the render()
which will trigger another render, and call this.setState
again, and the cycle repeats, and you'll get the error:
Uncaught Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.
You wouldn't call this.setState
directly in your render method and neither should you do that using hooks.
It's unclear what you're trying to achieve here, but I think what you want is to set the name only once, which you would do in componentDidMount
, and you can use the useEffect
hook to achieve that.
Or if you want "Brussels" to be the initial state, pass it as the value into 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/[email protected]/umd/react.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>
<div id="app"></div>
Upvotes: 6
Reputation: 79
Calling setHeading("Brussel") will cause re rendering again and again which in turns result in an infinite loop, to prevent that you need an event to change the header from "Heading" to "Brussels". Below code might help you
const Text = () => {
const initialState= 'Heading'.toUpperCase();
const [heading, setHeading] = useState(initialState);
return (
<header>
<h1>
{heading}
<button onClick= {() =>{setHeading("Brussel")}}>ChangeName</button>
</h1>
</header>
);
};
Upvotes: 1