React+TypeScript项目中useContext+useReducer点击无法触发dispatch问题
问题根因与修复方案
你代码里存在两个核心错误,导致点击后无法触发状态更新:
1. 重复创建Context实例,导致跨组件Context不连通
你在App.tsx和Cards.tsx中分别调用了一次createDataCtx,每次调用都会生成完全独立的Context对象,Cards组件消费的Context根本没有被外层App的Provider包裹,拿到的dispatch是你初始化时写的默认空函数,自然不会触发任何操作。
2. Reducer判断逻辑写反了参数
你在reducer里用switch(action.shortName)做判断,但实际上应该判断的是action.type,现在的逻辑只有当卡片的shortName刚好叫favorite/unFavorite时才会执行更新,正常业务下永远走default分支返回原state。
修复步骤
第一步:修改dataContext.tsx,全局复用同一个Context实例
在文件末尾添加如下代码,直接导出全局唯一的Context和Provider:
// 新增:只调用一次createDataCtx,生成全局唯一的实例供所有组件使用 export const [DataContext, DataProvider] = createDataCtx(reducer, initialState)
第二步:修改reducer的判断参数
把reducer里的switch判断对象从action.shortName改成action.type:
export function reducer(state: AppState, action: Action): AppState { // 这里修改为判断action.type switch(action.type){ case 'favorite': console.log('favorite action triggered!!') return state.map( (item: Bot) => item.shortName === action.shortName ? {...item, favorite: true} : item ) case 'unFavorite': console.log('unFavorite action triggered!!') return state.map( (item: Bot) => item.shortName === action.shortName ? {...item, favorite: false} : item ) default: return state } }
第三步:修改App.tsx,直接导入已经创建好的Provider
删除App里调用createDataCtx的逻辑,直接用导出的DataProvider:
import { DataProvider } from './dataContext.tsx' function App() { return ( <DataProvider> <ThemeProvider theme={Theme}> <AppStyles> <Router> <Header /> <Content /> </Router> </AppStyles> </ThemeProvider> </DataProvider> ); }
第四步:修改Cards.tsx,直接导入已经创建好的Context
删除Cards里调用createDataCtx的逻辑,直接用导出的DataContext:
import { DataContext } from './dataContext.tsx' const Cards = () => { const {state, dispatch } = useContext(DataContext) // 剩余原有代码完全保持不变 }
额外检查项
确认你封装的FavoriteStar组件内部,确实把传入的onStarClick属性绑定到了可点击元素的onClick事件上,只要前面的修改完成,功能就能正常运行。
内容的提问来源于stack exchange,提问作者govijuan
相关产品推荐
相关产品推荐

