- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在我的一生中,我似乎无法删除有关我的 useEffect 缺少依赖项 fetchProfile() 的 ESlinting 警告。当我将 fetchProfile 添加到依赖项数组时,出现无限循环。我真的很感激任何可以帮助我消除这个警告的建议。代码如下:
import React, { useEffect, useContext, useReducer } from 'react'
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom'
import './App.css'
import { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles/'
import UserContext from './contexts/UserContext'
import jwtDecode from 'jwt-decode'
import axios from 'axios'
// utils
import reducer from './utils/reducer'
import themeFile from './utils/theme'
import AuthRoute from './utils/AuthRoute'
import UnAuthRoute from './utils/UnAuthRoute'
// Components
import NavBar from './components/NavBar'
// Pages
import Home from './pages/Home'
import Login from './pages/Login'
import Profile from './pages/Profile'
import SignUp from './pages/SignUp'
import Admin from './pages/Admin'
import Dashboard from './pages/Dashboard'
import Alumni from './pages/Alumni'
// context
import { ProfileContext } from './contexts/ProfileContext'
const theme = createMuiTheme(themeFile)
// axios.defaults.baseURL = `https://us-central1-jobtracker-4f14f.cloudfunctions.net/api`
const App = () => {
const initialState = useContext(UserContext)
const [user, setUser] = useContext(ProfileContext)
const [state, dispatch] = useReducer(reducer, initialState)
const fetchProfile = async token => {
await axios
.get(`/user`, {
headers: {
Authorization: `${token}`
}
})
.then(res => {
setUser(res.data)
})
.catch(err => console.log({ err }))
}
// keeps userContext authorized if signed in
useEffect(
_ => {
const token = localStorage.FBIdToken
if (token && token !== 'Bearer undefined') {
const decodedToken = jwtDecode(token)
if (decodedToken.exp * 1000 < Date.now()) {
localStorage.removeItem('FBIdToken')
dispatch({ type: 'LOGOUT' })
} else {
dispatch({ type: 'LOGIN' })
state.isAuth && fetchProfile(token)
}
} else {
dispatch({ type: 'LOGOUT' })
localStorage.removeItem('FBIdToken')
}
},
[state.isAuth]
)
return (
<MuiThemeProvider theme={theme}>
<UserContext.Provider value={{ state, dispatch }}>
<div className="App">
<Router>
<NavBar isAuth={state.isAuth} />
<div className="container">
<Switch>
<Route exact path="/" component={Home} />
<UnAuthRoute
path="/signup"
component={SignUp}
isAuth={state.isAuth}
/>
<UnAuthRoute
path="/login"
component={Login}
isAuth={state.isAuth}
/>
<AuthRoute
path="/profile"
component={Profile}
isAuth={state.isAuth}
/>
<AuthRoute
path="/dashboard"
component={Dashboard}
isAuth={state.isAuth}
/>
<Route path="/admin" component={Admin} isAuth={state.isAuth} />
<AuthRoute
path="/users/:id"
component={Alumni}
isAuth={state.isAuth}
/>
</Switch>
</div>
</Router>
</div>
</UserContext.Provider>
</MuiThemeProvider>
)
}
export default App
最佳答案
您可以执行以下两项操作之一:
将 fetchProfile
完全移出组件,并使用其结果,而不是让它直接调用 setUser
。
Memoize fetchProfile
这样,只有当它所依赖的东西发生变化时,你才创建一个新的(这是......永远不会,因为 fetchProfile
仅依赖于 setUser
,这是稳定的)。 (您可能会使用 useMemo
或其近亲 useCallback
来执行此操作,尽管理论上 useMemo
[因此 useCallback
] 是为了性能增强,而不是“语义保证。”)
对我来说,#1 是你最好的选择。在您的组件之外:
const fetchProfile = token => {
return axios
.get(`/user`, {
headers: {
Authorization: `${token}`
}
})
}
然后
useEffect(
_ => {
const token = localStorage.FBIdToken
if (token && token !== 'Bearer undefined') {
const decodedToken = jwtDecode(token)
if (decodedToken.exp * 1000 < Date.now()) {
localStorage.removeItem('FBIdToken')
dispatch({ type: 'LOGOUT' })
} else {
dispatch({ type: 'LOGIN' })
if (state.isAuth) { // ***
fetchProfile(token) // ***
.then(res => setUser(res.data)) // ***
.catch(error => console.error(error)) // ***
} // ***
}
} else {
dispatch({ type: 'LOGOUT' })
localStorage.removeItem('FBIdToken')
}
},
[state.isAuth]
)
由于该操作是异步的,因此如果组件同时重新渲染(这取决于您的用例),您可能希望取消/忽略它。
关于javascript - useEffect 缺少依赖项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60851216/
我知道没有数组的 useEffect() 只在第一次渲染时运行回调。 那么useEffect(()=>{},[])和没有useEffect()的区别是什么。 我的意思是: function myCom
我的场景很少,我想了解渲染和性能方面的差异。 下面显示的示例是一个简单的函数,但请考虑一个更复杂的函数以及一个异步函数。 场景 1:定义函数并在 useEffect 中调用它。 useEffect((
我需要添加一些与 React 之外的对象交互的事件处理程序(以 Google map 为例)。 在这个处理函数内部,我想访问一些可以发送给这个外部对象的状态。 如果我将状态作为依赖项传递给效果,它可以
要限制 useEffect 在第一个渲染上运行,我们可以这样做: const isFirstRun = useRef(true); useEffect (() => { if (isF
我有一个产品组件,它显示某个类别的产品。CategoryId 从路由参数中获取,然后用户可以对产品进行分页。所以有2个useEffect,一个是改变categoryId的时候,另一个是改变当前页码的时
我有一个产品组件,它显示某个类别的产品。CategoryId 从路由参数中获取,然后用户可以对产品进行分页。所以有2个useEffect,一个是改变categoryId的时候,另一个是改变当前页码的时
我的状态宽度随着窗口大小的调整而变化,showFilters作为 Prop 从true变为false。我想在卸载时删除监听器。因此,我为每个条件使用了三个 useState。那么,我可以做任何重构来在
我正在开发一个基于对象键管理字符串数组的函数。假设它看起来像这样: import React, { useState, useEffect } from "react"; import FieldCo
新的 React Hooks 功能很酷,但有时会让我感到困惑。特别是,我将此代码包装在 useEffect Hook 中: const compA = ({ num }) => { const [
我想将其转换为 useEffect钩: 代码 componentDidMount () { this.messagesRef.on('child_added', snapshot => {
这是我的代码部分。一切正常,但 eslint 给出错误。 React Hook useEffect has missing dependencies: 'dispatch' and 'getData'
当组件安装时,我需要从两个 API 端点获取数据。现在我有: useEffect(() => { dispatch(loadSomeDataOne()); }, [dispatch])
当组件安装时,我需要从两个 API 端点获取数据。现在我有: useEffect(() => { dispatch(loadSomeDataOne()); }, [dispatch])
在 React DOCs 中,关于 useEffect() 钩子(Hook),我们得到: “使用 useEffect 安排的效果不会阻止浏览器更新屏幕。” Tip Unlike componentDi
我一直试图了解何时取消订阅(useEffect 中的回调)被准确调用。 这是codepen链接:https://codepen.io/deen_john/pen/eYmNdMy 代码 : const
当对状态、效果、上下文等使用钩子(Hook)时,我这样做: import React, { useState, useEffect, useContext } from 'react'; 但是,我注意
我正在尝试像下面这样的 useEffect 示例: useEffect(async () => { try { const response = await fetch(`ht
我在我的 React 应用中构建了一个简单的点赞、书签功能。 const [liked, setLiked] = useState(); const [bookmarked, setBookmarke
我想了解为什么在代码块的底部使用 useEffect,以及它的用途。我认为它与组件生命周期和避免无限循环有关,但我无法完全理解它并全面了解这一切。如果有人能向我解释幕后发生的事情,以及 useEffe
useEffect(() => { return history.replace({ pathname: "path/A", }); }, []); useEffe
我是一名优秀的程序员,十分优秀!