Redux dispatch触发TypeError:'listener2 is not a function'问题求助
问题解决方法
错误原因分析
store.subscribe()要求传入函数类型的监听回调,但你把createRoot.render()的返回值(实际为undefined)赋值给root并传给subscribe,导致Redux尝试调用非函数对象,触发listener2 is not a function错误。- 直接给App传递
store.getState()的静态快照,组件无法自动响应Store状态变化,因此移除subscribe后错误消失,但组件不会更新。
正确修复步骤
1. 用React-Redux的Provider连接Store
React-Redux是Redux官方React绑定库,自动处理组件与Store的连接、状态更新后的组件重渲染,无需手动调用subscribe。
修改index.js:
import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; import App from './App'; import store from './store.js'; import { Provider } from 'react-redux'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <React.StrictMode> <Provider store={store}> <App /> </Provider> </React.StrictMode> );
2. 在组件中使用官方Hook获取dispatch和状态
不要手动传递dispatch和state,改用React-Redux提供的useDispatch和useSelector Hook,这是Redux官方推荐的组件用法。
修改App.js:
import './App.css'; import PostContainer from './features/post/PostContainer'; import { useDispatch, useSelector } from 'react-redux'; import { addPost } from './features/post/PostContainerSlice'; function App() { const dispatch = useDispatch(); const postContainer = useSelector(state => state.postContainer); // 避免组件顶层直接dispatch导致无限重渲染,放在useEffect中 React.useEffect(() => { dispatch(addPost('test')); }, [dispatch]); console.log(postContainer); return ( <div className="App"> <PostContainer /> </div> ); } export default App;
3. 移除错误的subscribe调用
使用Provider和Hook后,无需手动调用store.subscribe(root),直接删除该行代码即可。
额外注意事项
- 优先使用slice导出的action creator(如
addPost)创建动作,避免手动编写type字符串引发拼写错误。 - 禁止在组件顶层直接调用
dispatch,必须放在useEffect或事件处理函数(如按钮点击回调)中,防止无限重渲染。 - 组件必须返回有效的JSX,原App组件缺少return语句,会导致渲染异常。
内容的提问来源于stack exchange,提问作者scmgames2
相关产品推荐
相关产品推荐

