React Router从useEffect重新发送我的组件,如何缓解这种情况



我的应用程序组件中有一个useEffect(),它检查本地存储中是否有本地存储的用户,如果有,它会用信息更新我的redux状态。这是非常有问题的,因为当一个人去我的路线player/example时,我的应用程序组件会渲染Player组件,然后当用户状态从useEffect更新时,它会再次渲染路线上的Player组件。因此,运行组件两次,而Player组件中的任何useEffects(如获取数据)都会调用数据两次!

是绝对有办法解决这个问题,还是我的功能做错了。它让我发疯

总之,基本上Player组件会被渲染两次,因为最初应用程序在没有用户的情况下渲染它,当从useEffect中找到用户时,它会再次渲染它,即使您与urlplayer/example保持在同一页面上

// React 
import { useEffect } from 'react'

// Redux
import { useSelector, useDispatch } from 'react-redux'

// React Reducer
import { Routes, Route } from "react-router-dom"
import { loginUser, logoutUser } from './reducers/user';

// Components
import Login from './components/Login';
import Player from './components/Player';

function App() {
console.log("app component")
const dispatch = useDispatch()
const user = useSelector(state => state.user)

useEffect(() => {
const loggedUserJSON = window.localStorage.getItem('loggedUser')
if (loggedUserJSON) {
const user= JSON.parse(loggedUserJSON)
dispatch(loginUser(user))
}
}, [])

// User not logged in
if (!user) { 
return (
<Routes>
<Route path="/login" element={<Login/>}/>
<Route path="/" element={<Login/>} />
<Route path="/player/:username" element={<Player/>}/> 
</Routes>
)
}

// User logged in
return (
<div>
<h1><button onClick={() => dispatch(logoutUser())}>LOG OUT</button></h1>
<Routes>
<Route path="/login" element={<h1>HOME</h1>}/>
<Route path="/" element={<h1>HOME</h1>} />
<Route path="/player/:username" element={<Player/>}/> 
</Routes>
</div>
);
}

export default App;

这是因为App组件中有两个返回语句。在您的情况下,播放器组件没有重新渲染,它只是切换到其他播放器组件,因为您返回了用户在应用程序组件中存在的另一个元素。

为了解决这个问题,无论用户是否存在,都必须返回一个元素。

这是我的密码。

function App() {
console.log("app component")
const dispatch = useDispatch()
const user = useSelector(state => state.user)
useEffect(() => {
const loggedUserJSON = window.localStorage.getItem('loggedUser')
if (loggedUserJSON) {
const user = JSON.parse(loggedUserJSON)
dispatch(loginUser(user))
}
}, [])

return (
<div>
{user && <h1><button onClick={() => dispatch(logoutUser())}>LOG OUT</button></h1>}
<Routes>
<Route path="/login" element={<Login />} />
<Route path="/" element={<Login />} />
<Route path="/player/:username" element={<Player />} />
</Routes>
</div>
);
}

在这段代码中,Route组件是同一个组件,而不是新组件,道具也没有改变,所以不会重新渲染。您必须实现对用户存在的登录组件视图的更改,因为此逻辑属于登录组件,而不是应用程序组件。

相关内容