javascript - ReactJs:PrivateRoute 组件被调用两次
问题描述
我有这个用于管理身份验证的 privateRoute 组件:
const PrivateRoute = ({ component: Component, auth, ...rest }) => {
// This gets logged twice when I navigate in the app
// Using history.push("/url")
// And gets logged once when I type the url and hit enter on the browser
console.log(
"===============INSIDE PrivateRoute Component========================"
);
return (
<Route
{...rest}
render={(props) =>
auth.isAuthenticated === true ? (
<Component {...props} />
) : (
<Redirect to="/login" />
)
}
/>
);
};
奇怪的是,当我在应用程序中导航时,这个组件会被记录两次。例如,当我点击触发此代码的按钮时:
this.props.history.push("/edit-page-after-login");
我在 App.js 中有这个:
<PrivateRoute
path="/edit-page-after-login"
component={EditProfileAfterLogin}
/>
我有一个在该路线中呈现的组件:
export default class EditProfileInSettings extends Component {
componentDidMount() {
console.log(
" ~ file: EditProfileInSettings.js ~ line 5 ~ EditProfileInSettings ~ componentDidMount ~ componentDidMount"
);
}
render() {
return <div>Test</div>;
}
}
因此,当我使用 导航到该组件时history.push
,会记录以下内容:
===============INSIDE PrivateRoute 组件=========================
~ 文件:EditProfileInSettings.js ~ 行5 ~ EditProfileInSettings ~ componentDidMount ~ componentDidMount
================INSIDE PrivateRoute 组件========================
由于某些奇怪的原因,PrivateRoute 组件被称为TWICE,这导致我尝试实现的逻辑出现一些问题。
但是,当我在浏览器中写入 url 并输入时,它的行为正确,它只被称为ONCE:
===============INSIDE PrivateRoute 组件========================
~ 文件:EditProfileInSettings.js ~ 行5~EditProfileInSettings~componentDidMount~componentDidMount
知道这里发生了什么吗?
编辑1:我注意到这个错误只发生在我对组件内的后端进行API调用时:
class PrivateRouteTestComponent extends Component {
componentDidMount() {
console.log("PrivateRouteTestComponent.componentDidMount is called!");
// If I comment this out, the problem will not occur.
// It only occurs with this line
// It does an API call to the backend to get user profile
this.props.getAuthenticatedUserProfile();
}
render() {
return (
<div>
<button
onClick={() => {
this.props.history.push("/videos-page");
}}
>
Home
</button>
<h6>Private route test component</h6>
</div>
);
}
}
编辑2:我终于找到了为什么会发生这个错误。调用一个向 store 分派某些东西的函数将更新 ,PrivateRoute
因此它将再次被调用:
class PrivateRouteTestComponent extends Component {
componentDidMount() {
console.log("PrivateRouteTestComponent.componentDidMount is called!");
// This doesn't cause the problem
testBackendCall();
// This causes the problem
// Because it dispatches an action to the store
// So PrivateRoute gets updated
this.props.testBackendCallThatDispatchesSomethingToTheStore();
}
render() {
return (
<div>
<button
onClick={() => {
this.props.history.push("/videos-page");
}}
>
Home
</button>
<h6>Private route test component</h6>
</div>
);
}
}
解决方案
您正在混合功能组件和基于 React 类的组件,并期望登录PrivateRoute
和登录在EditProfileInSettings
渲染周期的同一时刻完成 - 但事实并非如此。
在EditProfileInSettings
中,您登录安装阶段( componentDidMount
),该阶段在组件的渲染中发生一次(如果未卸载)。
在PrivateRoute
中,您登录渲染阶段(认为相当于render
在 class 上Component
),每次 React 需要更新您的组件时都会发生这种情况,因为它的 props 被更改。
如果您希望两个日志记录等效,请将您的日志记录放在您的 auseEffect()
上PrivateRoute
,或者将您的日志记录render()
放在您的EditProfileInSettings
.
然后,要知道为什么你的功能组件被渲染了两次,记录你所有的 props 并找出两个循环之间的差异。
推荐阅读
- python - DataFrame中apply函数的输出
- firebase - Firebase Messaging : Successful but not delivered
- nginx - 403 尝试列出 Nginx 目录时
- performance - 基于 CPU 时间的近似处理能力
- php - 转换为 PDO 后数据不显示在 ListView
- ios - calling a class shared function from action
- c++ - 错误:ISO C++ 禁止变长数组 'subVec' [-Werror=vla]
- java - 如何打印数组的特定元素
- c# - 如何安装 Topshelf.Runtime.Windows.WindowsHostSettings 服务
- c# - Xamarin 选项卡式表单应用程序模板:微调器不停止,异步任务无效