reactjs - 路由更改时防止 React 组件重新渲染
问题描述
我正在使用 react-router-dom。
假设我有 2 个页面,例如主页和个人资料页面。两个页面都有一个名为 Header 的组件。
在 Header 组件中,使用 useEffect React Hook 我在后端服务器上调用获取请求并获取登录的用户数据。API 返回用户名、头像图像等(这不是问题)
事情是这样的。当我从“主页”跳转到“个人资料页面”时,Header 组件会重新渲染并将请求再次发送到服务器。每次我从主页跳转到个人资料页面或个人资料页面到主页时都会发生这种情况。并且 Header 上显示的数据会一直加载,直到获取的请求成功。
我想要像 Youtube 这样的东西。
标题组件
import {useState , useEffect} from 'react'
import Logo from './imgs/logo.png'
import {Link} from 'react-router-dom'
import { FaArrowRight , FaServicestack , FaFirstOrder} from "react-icons/fa";
import { BsPersonCheck , AiOutlineContacts } from "react-icons/all";
const ShowOrHideNav = ()=>{
var nav = document.getElementById('NavBarSpingbuck')
nav.classList.toggle('hidden')
}
const Header = () =>{
const [loggedIn , setLoggedIn] = useState(false)
const [user_data , setUserData] = useState(undefined)
const Logout = () =>{
localStorage.removeItem('sb_auth_token')
UpdateHeader()
}
const UpdateHeader = () =>{
const auth_token = localStorage.getItem('sb_auth_token')
if(auth_token){
console.log('sending request')
fetch(
'https://dummy_API_URL.dummy_domain.com/authentication/user/',
{
headers:{
Authorization : 'Token ' + auth_token,
},
}
)
.then(response => response.json())
.then(resp_data =>{
if(resp_data.status == 200){
setUserData(resp_data.data)
}
})
.catch(error =>{
console.log(error)
console.log('error')
})
setLoggedIn(true)
}
else{
setLoggedIn(false)
}
}
useEffect(()=>{
UpdateHeader()
} , [])
return(
<div className=' fixed top-0 z-50 w-full shadow bg-black bg-opacity-75 px-5' style={{backdropFilter:'blur(18px)'}}>
<div className='container py-2 flex items-center justify-between mx-auto relative'>
<div className='w-8 h-8 md:hidden flex flex-col justify-evenly items-end cursor-pointer group ' onClick={ShowOrHideNav}>
<span className='w-2 h-1 bg-white block rounded-full transition-all delay-150 duration-300 group-hover:w-8'></span>
<span className='w-4 h-1 bg-white block rounded-full transition-all duration-300 group-hover:w-8'></span>
<span className='w-8 h-1 bg-white block rounded-full '></span>
</div>
<div>
<Link to='/'>
<img src={Logo} className='w-32 ' />
</Link>
</div>
<div className='px-5'>
<ul className='items-center hidden p-4 md:p-0 md:flex absolute md:relative top-full md:top-0 w-full md:w-auto z-50 left-0 bg-white md:bg-transparent rounded-lg md:rounded-none transition-all duration-300' style={{animationIterationCount:1}} id='NavBarSpingbuck'>
<li className='hover:scale-110 duration-150 transform px-4 mb-4 md:mb-0' >
<Link className='flex flex-col items-center text-gray-800 md:text-white'>
<p>Jobs</p>
</Link>
</li>
<li className='hover:scale-110 duration-150 transform px-4 mb-4 md:mb-0' >
<Link className='flex flex-col items-center text-gray-800 md:text-white'>
<p>Services</p>
</Link>
</li>
<li className='hover:scale-110 duration-150 transform px-4 mb-4 md:mb-0' >
<Link className='flex flex-col items-center text-gray-800 md:text-white'>
<p>Place Order</p>
</Link>
</li>
<li className='hover:scale-110 duration-150 transform px-4 mb-4 md:mb-0' >
<Link className='flex flex-col items-center text-gray-800 md:text-white'>
<p>About</p>
</Link>
</li>
<li className='hover:scale-110 duration-150 transform px-4 mb-4 md:mb-0' >
<Link className='flex flex-col items-center text-gray-800 md:text-white'>
<p>Contact</p>
</Link>
</li>
</ul>
</div>
<div className='account_bar'>
{
loggedIn?
<div className='flex items-center cursor-pointer group relative py-1'>
<div className='mr-3 rounded-full w-10 h-10 bg-center bg-cover' style={{backgroundImage:'url(https://pixinvent.com/materialize-material-design-admin-template/app-assets/images/user/12.jpg)'}}>
</div>
{
user_data && user_data.username ?
<p className='text-white'>{user_data.username}</p>: <p className='text-white'>User</p>
}
<div className='bg-white rounded-md py-2 w-28 absolute top-full shadow-2xl hidden group-hover:block'>
<ul>
<li className='px-2 py-1 hover:bg-blue-100'>
<Link className='block' to='/profile/' >Profile</Link>
</li>
<li className='px-2 py-1 hover:bg-blue-100' onClick={()=>{Logout()}}>
Logout
</li>
</ul>
</div>
</div>
:
<Link to='/authentication/login/' >
<div className='bg-yellow-600 py-0.5 px-2 rounded flex items-center justify-center hover:bg-yellow-700 transition-all duration-300'>
<p className='text-white pr-1'>Sign in</p>
<FaArrowRight className='text-white text-sm' />
</div>
</Link>
}
</div>
</div>
</div>
)
}
export default Header
解决方案
提取Header
组件并将其放置在与Switch
组件相同的水平面上。
<Router>
<Header />
<Switch>
<Route path="/">
<Home />
</Route>
<Route path="/profile">
<Profile />
</Route>
</Switch>
</Router>
推荐阅读
- java - 从 mybatis xml 查询生成 sql 查询
- python - 从字典值中删除外部列表
- linux - 如何转义在 bash 脚本命令行中传递的参数
- java - 如何使用三元运算符中的枚举检查两个条件?
- node.js - Node.js 中间件本地更新
- spring-boot - Spring Boot - Graphql - 从任意解析器代码访问标头
- c# - 在 Web 浏览器控件中单击图像等时如何始终在新的 IE 窗口中打开链接
- java - 在 IntelliJ 中查找整个项目中的所有匿名类
- reactjs - 错误:在 Function.Module._resolveFilename (module.js:470:15) 处找不到模块“webpack/lib/removeAndDo”
- r - 我正在尝试在 r 中运行一个嵌套的 for 循环,该循环减去数据框中变量的每一行