I have created one functional component that name is TopLocation() and i am calling this function to another component const handleChange = e => {
TopLocation(e.target.value)
}
function TopLocation (cityid=null) {
const[location,setLocation]=useState();
let city={city_id:(cityid==''?localStorage.getItem("location"):cityid)};
useEffect(()=> {
const fetchData= async()=>{
const result = await Locationapi(
city
);
console.log('result',result);
if(result.status==200){
setLocation(result.data);
}
}
fetchData();
},[]);
it's showing error.
Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
You might have mismatching versions of React and the renderer (such as React DOM)
You might be breaking the Rules of Hooks
You might have more than one copy of React in the same app
Don’t call Hooks inside loops, conditions, or nested functions
but you can call react hooks inside of your own custom hook
read more about hooks over here
https://reactjs.org/docs/hooks-intro.html
Related
When I run the below code I am getting: Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
You might have mismatching versions of React and the renderer (such as React DOM)
You might be breaking the Rules of Hooks
useEffect(() => {
if (user.email) {
const { data } = GetUserInfo(user.email);
}
}, [user.email]);
What I am trying to do is until I get the user email I will not run the getUserInfo query.
As mentioned in the other answer, you can only call hooks at the top level in the body of a functional component/custom hook.
I think you can achieve what you want using the enabled option in useQuery to enable/disable it based on a condition.
Docs example:
function Todos() {
const [filter, setFilter] = React.useState('')
const { data } = useQuery(
['todos', filter],
() => fetchTodos(filter),
{
// ⬇️ disabled as long as the filter is empty
enabled: !!filter
}
)
...
}
Reference:
https://tanstack.com/query/v4/docs/guides/disabling-queries
You can't call a hook inside another hook.
useEffect(() => {
if (user.email) {
const { data } = GetUserInfo(user.email);
}
}, [user.email]);
You have to call the hook outside useEffect hook
There are three common reasons you might be seeing it
You might have mismatching versions of React and React DOM.
You might be breaking the Rules of Hooks.
You might have more than one copy of React in the same app.
In your case you are breaking the rule of hooks that Call Hooks from React function components. GetUserInfo is also hook you are calling in a hook you need to call it outside of useEffect()
for reference documentation
I want to build a JSON file based on a bunch of recoil values, so I created a function that fetches all the recoilVaules and returns a JSON out of it, and I call it from a component.
The thing is that it gives me an error for using useRecoilValue outside a component.
besides moving the function inside the component (which will make the component look bad because there are a lot of values) or passing all the recoilValue as parameters to the function (same), what more can I do?
This is the general idea -
const ReactCom = () => {
getJson();
....
}
const getJson = () => {
let jsonFile = useRecoilValue(someAtom);
return jsonFile;
}
Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a
function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
This should work
const ReactCom = () => {
const json = useGetJson();
....
}
const useGetJson= () => {
let jsonFile = useRecoilValue(someAtom);
return jsonFile;
}
Unhandled Rejection (Error): Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
I don't understand why I break the rules.
The hook call should be allowed at this point.
Can someone tell me why the call is not accepted?
export const createMail =
(values: ValuesType): AppThunk =>
async (dispatch, getState) => {
const state = getState();
const { t } = useTranslation(["emails", "translation"]);
This is happening because of the second reason mentioned in the error. You can only use react hooks (useStates and ...), inside of a FUNCTION COMPONENT. What you have here not only isn't a function component (because of the camelCase) but you are using useState inside of another function which is returned by the formerly mentioned one.
I'm having the problem with calling useState hook in my component.
Everything is working fine. I can define props on Container as well as on Continer.Element.
But when I'm trying to call Hooks inside Container.Element - I'm getting an error.
const Container: React.FC<Props> & {Element: React.FC<ElementProps>} = () => {
return <Container.Element />
}
Container.Element = () => {
const [state, setState] = useState();
return <div>Some JSX code</div>
}
In your code, Container is a valid React component but not the Container.Element.
When you do Container.Element = () => {};: You are just declaring a js function that return some jsx called Element.
To use react hooks, you have to follow the rules of hooks :D
From the react docs :
Only Call Hooks at the Top Level
Don’t call Hooks inside loops, conditions, or nested functions.
Instead, always use Hooks at the top level of your React function.
By following this rule, you ensure that Hooks are called
in the same order each time a component renders.
That’s what allows React to correctly preserve the state
of Hooks between multiple useState and useEffect calls.
(If you’re curious, we’ll explain this in depth below.)
Only Call Hooks from React Functions
Don’t call Hooks from regular JavaScript functions. Instead, you can:
✅ Call Hooks from React function components.
✅ Call Hooks from custom Hooks (we’ll learn about them on the next page).
By following this rule, you ensure that all stateful logic in a component is clearly visible from its source code.
If you need to use hook in your example, you will have to use it in the Container component.
const Container: React.FC<Props> & {Element: React.FC<ElementProps>} = () => {
const [state, setState] = useState();
return <Container.Element />
}
Container.Element = () => {
return <div>Some JSX code</div>
}
There is this section on React Hooks that I don't really understand what it is saying:
Only Call Hooks from React Functions
Don’t call Hooks from regular JavaScript functions. Instead, you can:
✅ Call Hooks from React function components.
✅ Call Hooks from custom Hooks (we’ll learn about them on the next page).
By following this rule, you ensure that all stateful logic in a component is clearly visible from its source code.
What does it mean to only call Hooks from React function components and how is a React function different than what I would call a regular functional component?
In my mind they're the same:
const App = () => {
useEffect(() => //do stuff);
return (
// return some sort of stuff here
)
}
The reason I ask is the eslint I have for hooks is complaining about the way I'm using useState here:
const checkPermissions = () => { //when I change this to 'usePermissions', it works fine
const [locPermission, setLocPermission] = useState(null); // eslint error here
//'React Hook "useState" is called in function "checkPermissions" which
//is neither a React function component or a custom React Hook function.'
//Check for and set state for permissions here
return locPermission;
};
What they mean is the entry point for a set of hooks should be within a React component and not elsewhere if it is used as a hook e.g. in this very arbitrary/simple example here:
my-utils/useCustomHook.js arbitrary custom hook
import { setState } from 'React'
export default function useCustomHook() {
const [state, setState] = useState(()=> 'anyRandomState');
// ...possibly re-using other custom hooks here,
// then returning something for our component to consume
}
MyComponent.js Your React component
import React, { setState } from 'react'
import useCustomHook from 'my-utils/useCustomHook'
function MyComponent() {
const offDaHook = useCustomHook();
return (
<div>
Hi, I'm your component with a custom hook.
I see that the value returned was {offDaHook}.
</div>
);
}
random-other-business-logic.js another file which does other things that does not include rendering
import useCustomHook from `my-utils/useCustomHook.js`
useCustomHook(); // Arbitrarily calling from non React component!
// do other things...
One reason ESLint could/would complain is hooks should be formatted as useXXX e.g. in your case, rather than checkPermissions, something like usePermissionChecker (or useCheckPermissions depending on how you think in code) should get the linter to recognize that this function is a custom hook.
I also agree -- this phrasing could probably be improved -- the custom rules of hooks threw me for a little bit of a loop at first as well. I am not 100% sure why this is the case but this is just what I got from that.
I am not sure if React internally appends other variables to hooks such as counting their instances/prototypes but guessing that if the React team doesn't, they would like to reserve the right to do that going forward. In either case, it is a lot cleaner to separate your React-state code from your non-React business logic and hooks using the useHooks convention as they are a little bit funky with their nuances.
Definitely something interesting to look into and wish I could tell you more, but this is just from another user-world programmer currently.