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