[英]useEffect hook not triggered when state is updated somewhere else
我在尝试收听此应用程序中的 state 更改时遇到了一些问题。 基本上我期待在一些 state 改变后会触发一个 useEffect 钩子,但什么都没有发生。
这就是我得到的
索引.jsx
// this is a simplification.
// I actually have a react-router-dom's Router wrapping everything
// and App is a Switch with multiple Route components
ReactDOM.render(
<Provider>
<App>
</Provider>
, document.getElementById('root'));
使用Session.jsx
export const useSession = () => {
const [session, setSession] = useState(null)
const login = useCallback(() => {
// do something
setSession(newSession)
})
return {
session,
setSession,
login
}
}
提供者.jsx
const { session } = useSession();
useEffect(() => {
console.log('Print this')
}, [session])
// more code ...
应用程序.jsx
export function Login() {
const { login } = useSession();
return <button type="button" onClick={() => { login() }}>Login</button>
}
好吧,我有这个父组件 Provider 正在监视 session state,但是当它更新时,永远不会调用提供者的 useEffect。
仅当setSession
在相同的钩子/方法中调用时才会触发useEffect
。 例如,如果我在Provider
中导入setSession
并在那里使用它,则将触发useEffect
; 或者,如果我在useSession
方法中添加一个useEffect
,它将在login
更新 state 时被触发。
useEffect
的回调只被调用一次,当组件被挂载时,而不是当 state 被改变时。
我怎样才能实现这种行为? 每次更新session
时都会触发Provider
的useEffect
吗?
提前致谢!
我认为这只是对自定义钩子如何工作的一点误解。组件的每个实例都有自己的 state。 让我举一个简单的例子来说明这一点。
function App () {
return (
<div>
<ComponentA/>
<ComponentB/>
<ComponentC/>
<ComponentD/>
</div>
)
}
function useCounter() {
const [counter, setCounter] = React.useState(0);
function increment() {
setCounter(counter+1)
}
return {
increment, counter, setCounter
}
}
function ComponentA() {
const { counter, increment }= useCounter()
return (
<div>
<button onClick={()=>increment()}>Button A</button>
ComponentA Counter: {counter}
</div>
)
}
function ComponentB() {
const { counter, increment }= useCounter()
return (
<div>
<button onClick={()=>increment()}>Button B</button>
ComponentB Counter: {counter}
</div>
)
}
function ComponentC() {
const { counter }= useCounter();
return (
<div>
ComponentC Counter: {counter}
</div>
)
}
function ComponentD() {
const [toggle, setToggle] = React.UseState(false);
const { counter }= useCounter();
React.useEffect(() => {
setInterval(()=>{
setToggle(prev => !prev);
}, 1000)
})
return (
<div>
ComponentD Counter: {counter}
</div>
)
}
从上面的代码中可以看出,点击Button A
增加计数不会影响ComponentB
的计数实例。这是因为组件的每个实例都有自己的 state 。 您还可以看到,单击任一按钮都不会触发ComponentC
重新呈现,因为它们不共享相同的实例。 即使我像在组件 D 中那样每隔一秒触发一次重新渲染,从而调用useCounter
, ComponentD
D 中的计数器仍然为 0。
解决方案然而,有多种方法可以让组件共享/监听相同的 state 更改
Provider
组件,并通过道具传递它使其对其他组件可见。But since you are dealing with auth and session management, I suggest you persist the session state in local storage or session storage, and retrieve it whenever you need it. 希望有帮助
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.