Home > Mobile >  How to resolve the conditional call of React Hook "useState"
How to resolve the conditional call of React Hook "useState"

Time:08-04

I'm using a slugged, dynamic routing page in next JS, along with a small useState functionality for the radio button of a pricing cart:

 const Video = (props) => {
 const router = useRouter()
 const { video } = router.query
 const videoData = GeneralVideo.find((d) => d.link === video)
 if (!videoData) {
 return null
 }
 const { videoID, videolink, videoLinkDeep, videoTitle, id, thumb, thumbDeep, videoCategory, categoryLink, link } =
 videoData

 const [price, setPrice] = useState();

 // this function will be called when a radio button is checked
 const handleChange = (e: { target: { value: SetStateAction<undefined>; }; }) => {
     setPrice(e.target.value);
     }

I'm getting an:

27:28  Error: React Hook "useState" is called conditionally. React Hooks must be called in the exact same order in every component render.

out of this during the build. The only other component where this useState example is used, is formatted as:

     function VideoHero() {

 const [price, setPrice] = useState();

 // this function will be called when a radio button is checked
 const handleChange = (e: { target: { value: SetStateAction<undefined>; }; }) => {
     setPrice(e.target.value);
     }

where no error occurs.

I'm left uncertain on how to precisely realign the initial format to fix the error

CodePudding user response:

You cannot call react hooks conditionally. Even if it is called at the top level of a function, your hook is called conditionally depending on the value of videoData. You can fix your issue by moving the useState to before the if condition.

const Video = (props) => {
 const router = useRouter()
 const { video } = router.query
 const [price, setPrice] = useState();
 const videoData = GeneralVideo.find((d) => d.link === video)
 if (!videoData) {
 return null
 }
 const { videoID, videolink, videoLinkDeep, videoTitle, id, thumb, thumbDeep, videoCategory, categoryLink, link } =
 videoData



 // this function will be called when a radio button is checked
 const handleChange = (e: { target: { value: SetStateAction<undefined>; }; }) => {
     setPrice(e.target.value);
     }

CodePudding user response:

React assign return values of its hooks by their call order, which needs to not change from one render to another, so you shouldn't miss with that order, by for example calling conditionally a hook. Which what you did by these lines:

 if (!videoData) {
 return null
 }

all what you need to do is to move this block after all your hooks

  • Related