You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

其他组件更新共享状态后,如何触发HomeScreen组件的useEffect?

问题根源

你当前的useWebSockets自定义Hook存在核心问题:每次在不同组件中调用这个Hook时,都会创建一套独立的useState状态。也就是说,HomeScreen组件和WebSocket组件里的shouldFetchApplications完全是两个互不相干的变量——WebSocket组件调用setShouldFetchApplications(true)时,只会修改它自己内部的状态,HomeScreen组件的状态根本没变化,自然不会触发依赖该状态的useEffect。

解决方案

要实现跨组件的状态同步,你需要把状态放到一个两个组件都能访问的共享容器里,常用的两种方式如下:

方式一:状态提升到共同父组件

如果两个组件的层级不深,直接把状态提到它们的共同父组件中,通过props传递给子组件即可:

1. 改造共同父组件

import { useState } from 'react'
import HomeScreen from './HomeScreen'
import WebSocketComponent from './WebSocketComponent'

const ParentComponent = () => {
  // 把状态放在父组件中,作为共享状态
  const [shouldFetchApplications, setShouldFetchApplications] = useState(false)

  return (
    <>
      <HomeScreen 
        shouldFetchApplications={shouldFetchApplications}
        setShouldFetchApplications={setShouldFetchApplications}
      />
      <WebSocketComponent 
        setShouldFetchApplications={setShouldFetchApplications}
      />
    </>
  )
}

export default ParentComponent

2. 修改HomeScreen组件

不再调用原useWebSockets,直接接收父组件传递的props:

type Props = {
  shouldFetchApplications: boolean
  setShouldFetchApplications: (value: boolean) => void
}

const HomeScreen = ({ shouldFetchApplications, setShouldFetchApplications }: Props) => {
  // ...其他代码

  useEffect(() => {
    console.log(shouldFetchApplications)
    // 执行你需要的操作
  }, [shouldFetchApplications])

  // ...其他代码
}

3. 修改WebSocket组件

同样接收父组件传递的props:

type Props = {
  setShouldFetchApplications: (value: boolean) => void
}

const WebSocketComponent = ({ setShouldFetchApplications }: Props) => {
  // ...其他代码

  const onTaskUpdate = () => {
    setShouldFetchApplications(true)
  };

  // ...其他代码
}

方式二:用React Context共享状态

如果组件层级较深,props传递太繁琐,可以用React Context封装共享状态:

1. 创建WebSocketContext

// WebSocketContext.tsx
import { createContext, useContext, useState, ReactNode } from 'react'

type WebSocketContextType = {
  shouldFetchApplications: boolean
  setShouldFetchApplications: (value: boolean) => void
}

// 创建Context容器
const WebSocketContext = createContext<WebSocketContextType | undefined>(undefined)

// 封装Provider组件,提供共享状态
export const WebSocketProvider = ({ children }: { children: ReactNode }) => {
  const [shouldFetchApplications, setShouldFetchApplications] = useState(false)

  return (
    <WebSocketContext.Provider value={{ shouldFetchApplications, setShouldFetchApplications }}>
      {children}
    </WebSocketContext.Provider>
  )
}

// 封装自定义Hook,简化Context调用
export const useWebSocketContext = () => {
  const context = useContext(WebSocketContext)
  if (!context) {
    throw new Error('useWebSocketContext必须在WebSocketProvider内部使用')
  }
  return context
}

2. 在根组件中包裹Provider

// App.tsx
import { WebSocketProvider } from './WebSocketContext'
import HomeScreen from './HomeScreen'
import WebSocketComponent from './WebSocketComponent'

const App = () => {
  return (
    <WebSocketProvider>
      <HomeScreen />
      <WebSocketComponent />
    </WebSocketProvider>
  )
}

export default App

3. 修改HomeScreen组件

使用自定义的Context Hook获取共享状态:

import { useWebSocketContext } from './WebSocketContext'

const HomeScreen = () => {
  const { shouldFetchApplications, setShouldFetchApplications } = useWebSocketContext()

  // ...其他代码

  useEffect(() => {
    console.log(shouldFetchApplications)
    // 执行你需要的操作
  }, [shouldFetchApplications])

  // ...其他代码
}

4. 修改WebSocket组件

同样使用Context Hook获取状态修改方法:

import { useWebSocketContext } from './WebSocketContext'

const WebSocketComponent = () => {
  const { setShouldFetchApplications } = useWebSocketContext()

  // ...其他代码

  const onTaskUpdate = () => {
    setShouldFetchApplications(true)
  };

  // ...其他代码
}

内容的提问来源于stack exchange,提问作者TreyCollier

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 13:45:35