React检测到Hook的顺序发生了变化



我正在尝试显示一些基于从API获得的用户数据的卡片。但这个错误不断显示:`警告:React检测到PlanCard调用的Hooks的顺序发生了变化。如果不加以修复,这将导致错误。欲了解更多信息,请阅读挂钩规则

上一次渲染下一次渲染

  1. useState useState

  2. useState useState

  3. useState useState

  4. useEffect useEffect

  5. 未定义的useContext

    ^^^^^^^^^^^^^^`

这是我所有的PlanCard文件

const [loading, setLoading] = useState(false),
[showAlert, setShowAlert] = useState(false);
let headless = typeof window !== 'undefined' &&
window.location.search.includes('?headless'),
platform =
typeof window !== 'undefined' &&
window.location.search.includes('platform=')
? new URL(window.location.href).searchParams.get('platform')
: false,
access_token =
typeof window !== 'undefined' &&
window.location.search.includes('access_token=')
? new URL(window.location.href).searchParams.get('access_token')
: false,
plans = [],
payment_plan = null,
plan_id = null,
modal = null,
purchased_from = null;
if (headless && access_token) {
payment_plan = useFetchData(access_token);
plan_id = payment_plan.plan_id;
} else { 
// ToDo:
}
if (typeof plan_id === 'string') {
plans = getPlanCards(plan_id, payment_plan.current_plan_status.toLowerCase());
purchased_from = payment_plan.purchased_from;
modal = getPlanCardsANAAlert(purchased_from);
}
}; 

这也是我的fetchPlan代码:

import axios from 'axios';
const useFetchData = (access_token) => {
const [plan, setPlan] = useState({});
let componentMounted = true;
useEffect(() => {
const fetchData = async () => {
try {
const response = await axios.get(
`${process.env.GATSBY_API_URL}user/plan/current_plan_detail?token=${access_token}`
);
if (componentMounted) {
setPlan(response.data);
}
} catch (error) {
console.error(error);
}
};
fetchData();
return () => {
componentMounted = false;
};
}, []);
return plan;
};
export default useFetchData;

if语句中有一个钩子

if (headless && access_token) {
payment_plan = useFetchData(access_token);
plan_id = payment_plan.plan_id;
}

这使得您的钩子在组件的渲染之间不稳定,React使用钩子来确定组件的状态,并跟踪组件在数组中定义的钩子,如果它们在渲染之间不同,这意味着它无法正确比较状态。看看这里。

要解决这个问题,你可以使用这样的东西:

const payment_plan = useFetchData(access_token);
if(headless && payment_plan) {
...
} else {
...
}

React文档说明:

仅呼叫顶层的挂钩

不要在循环、条件或嵌套函数中调用Hook。相反,始终在React函数的顶层使用Hooks,在任何提前返回之前。通过遵循此规则,您可以确保每次渲染组件时,都会以相同的顺序调用挂钩。这就是React正确保持Hooks状态的原因在多个useState和useEffect调用之间。

您应该为挂钩使用相同的流,在页面的重新呈现过程中不能有不同的挂钩

我最近看到了这个bug,看起来如下:


警告:React检测到DashboardSidebar调用的Hooks的顺序发生了变化。如果不加以修复,这将导致错误。

下一次渲染
上一次渲染
useContext useContext
useContext useContext
useContext useContext
useDebugValue useDebugValue
useState useState
useEffect useEffect
undefined useContext

相关内容

最新更新