React+Redux集成Firebase认证报错:Connect(WithAuthentication)找不到store
嘿,这个报错我见得挺多的,本质就是你的Redux Connect 组件找不到store的上下文——因为你的WithAuthentication HOC和Redux的Provider层级没搭对,再加上你还要传递history,咱们一步步来搞定:
1. 先理清核心问题
报错提示Connect(WithAuthentication)找不到store,说明被connect包裹的组件(或者HOC)不在Redux Provider的覆盖范围内。同时你要传递history,得确保路由和Redux的上下文能同时覆盖整个应用。
2. 调整应用层级(关键步骤)
你需要把Provider放在最外层,紧接着包裹React Router的Router(用自定义history的话),然后再是你的HOC组件。这样整个应用的所有组件(包括HOC和Redux连接的组件)都能拿到store和history上下文。
第一步:创建自定义history对象(如果需要全局使用)
如果你想在组件外或者HOC里直接调用history.push之类的方法,先单独创建一个history文件:
// src/history.js import { createBrowserHistory } from 'history'; export default createBrowserHistory();
第二步:重构入口文件的层级
在index.js里把Provider、Router和你的应用组件按顺序包裹:
// src/index.js import React from 'react'; import ReactDOM from 'react-dom'; import { Provider } from 'react-redux'; import { Router } from 'react-router-dom'; // 用Router而非BrowserRouter,因为要传自定义history import store from './store'; // 你的Redux store配置 import history from './history'; import App from './App'; ReactDOM.render( <Provider store={store}> {/* 把自定义history传给Router,让全局都能访问到 */} <Router history={history}> <App /> </Router> </Provider>, document.getElementById('root') );
3. 修复HOC的props传递
你的WithAuthentication HOC必须把接收到的所有props(包括Redux注入的props)传递给被包裹的组件,不然connect注入的状态和方法会丢失。比如:
// src/components/WithAuthentication.js const WithAuthentication = (WrappedComponent) => { class WithAuth extends React.Component { // 这里写你的Firebase认证逻辑,比如监听用户登录状态 componentDidMount() { this.unsubscribeAuth = firebase.auth().onAuthStateChanged(user => { // 处理用户状态变化 }); } componentWillUnmount() { this.unsubscribeAuth(); } render() { // 关键:把所有props传递给被包裹的组件 return <WrappedComponent {...this.props} />; } } return WithAuth; }; export default WithAuthentication;
4. 正确使用HOC和Redux connect
确保你的业务组件先被connect包裹,再被WithAuthentication包裹(或者反过来也行,只要都在Provider内部)。比如:
// src/components/MainContent.js import { connect } from 'react-redux'; import WithAuthentication from './WithAuthentication'; const MainContent = ({ user, someReduxState }) => { // 使用Redux状态和Firebase用户信息 return ( <div> <p>当前用户:{user?.email}</p> <p>Redux状态:{someReduxState}</p> </div> ); }; const mapStateToProps = (state) => ({ someReduxState: state.yourReducer.someState }); // 先connect,再用HOC包裹 export default WithAuthentication(connect(mapStateToProps)(MainContent));
5. 关于history的传递
- 如果用了自定义
history,你可以在任何组件或HOC里直接import它使用:import history from '../history'; // 比如在HOC里跳转 history.push('/dashboard'); - 如果用React Router v5,也可以用
withRouterHOC把history注入到组件props里;v6的话用useNavigate钩子即可。
这样调整后,Connect组件就能从Provider的上下文中拿到store,同时history也能在全局正常使用,报错应该就消失了!
内容的提问来源于stack exchange,提问作者Thibault Jp

