问题
I'm trying to do my exportable package in which I create the redux store. This is the code:
import React from "react";
import { Provider } from "react-redux";
import { ErrorPage } from "../components/shared";
import { MyCoreApplication } from "./MyCoreApplication";
import { configureStore } from "../tools/configureStore";
import { createCoreHelp } from "./createCoreHelp";
export const MyCore = ({ withLogs, applicationSagas, applicationReducers, app, cookieInfo }) => {
const help = createCoreHelp(applicationSagas, applicationReducers, app);
if (help.error) return <ErrorPage errorMessage={help.error} tooltipMessage={help.tooltip} />;
else {
const store = configureStore(withLogs, applicationSagas, applicationReducers);
return (
<Provider store={store}>
<MyCoreApplication app={app} cookieInfo={cookieInfo} />
</Provider>
);
}
};
MyCoreApplication is the same:
import React, { useEffect } from "react";
import { useSelector, useDispatch } from "react-redux";
import { IntlProvider } from "react-intl";
import { BrowserRouter as Router } from "react-router-dom";
import { CookieBar, ErrorPage, LoadingSpinner, Notification } from "../components/shared";
import { getConfig, getConfigStore, fetchConfigEnded, isMobileMode, setMobileMode } from "../modules/configuration";
import { getLocale, setLocale, getMessages, fetchMessages } from "../modules/language";
export const MyCoreApplication = ({ app, cookieInfo }) => {
const dispatch = useDispatch();
const config = useSelector(getConfigStore);
const configLoaded = useSelector(fetchConfigEnded);
const mobileMode = useSelector(isMobileMode);
const messages = useSelector(getMessages);
const locale = useSelector(getLocale);
const actions = {
getConfig: () => dispatch(getConfig()),
setLocale: (locale) => dispatch(setLocale(locale)),
fetchMessages: (locale) => dispatch(fetchMessages(locale)),
setMobileMode: (checkMobile) => dispatch(setMobileMode(checkMobile)),
};
if (config === null && !configLoaded) dispatch(getConfig());
else {
if (!locale && config) actions.setLocale(config.defaultLanguage);
}
return config ? (
<IntlProvider messages={messages} locale={locale} defaultLocale={config.defaultLanguage}>
<Notification />
<Router>{app}</Router>
{cookieInfo && cookieInfo.useCookie && cookieInfo.infoLink && <CookieBar infoLink={cookieInfo.infoLink} />}
</IntlProvider>
) : configLoaded ? (
<ErrorPage />
) : (
<LoadingSpinner />
);
};
The goal of my package is to build a library which create redux store receiving sagas and reducer from the custom application. In this mode a developer who use this library hasn't to create the store because module has already done. In this project I use webpack and after run build and pack npm commands I've got a .tgz file that I use in a create-react-app project as a dependency. In this create-react-app project I use my package in the following mode:
import React from "react-dom";
import ReactDOM from "react-dom";
import { MyCore } from "my_core";
import { appSagas } from "./store/appSagas";
import { appReducers } from "./store/appReducers";
import { App } from "./container/App";
import "./styles/index.scss";
const wrapper = document.getElementById("container");
wrapper &&
ReactDOM.render(
<MyCore
withLogs={true}
applicationSagas={appSagas}
applicationReducers={appReducers}
app={<App />}
/>,
wrapper
);
And this is the App code:
import React from "react";
import { Layout } from "antd";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import { MyHeader as Header } from "../components/MyHeader.jsx";
import { Components } from "my_core";
const { MyFooter: Footer } = Components;
const { Content } = Layout;
export const App = () => (
<Layout>
<Router>
<Header />
<Content>
<Switch>
<Route exact path="/">
hello
</Route>
</Switch>
<Footer />
</Content>
</Router>
</Layout>
);
Finally, inside MyHeader I use useSelector as the following code shows:
import React from "react";
import { useSelector } from "react-redux";
import { Utility } from "my_core";
const { configUtils } = Utility;
export const MyHeader = () => {
const mobileMode = useSelector(configUtils.isMobileMode);
return mobileMode ? <div>Mobile Header</div> : <div>Desktop Header</div>;
};
When I start the create-react-app project I encounter this error:
useSelector() Error: Could not find react-redux context value; please ensure the component is wrapped in a <Provider>
The same identical code, if written inside MyCore package project, works fine. How can I solve this problem?
回答1:
At this link github.com/iBobo5/myCore.git you can find myCore project. It's enough to run npm install and npm run export to obtain .tgz file. Once it has been created copy in a create-react-app "test" project and install it with react and react-dom dependencies. Other dependencies are installed by the library. Inside "test" project try to replace the import as shown above and inside a component use useSelector or useDispatch. In this way you could be able to reproduce my issue
回答2:
The problem is probably that you have react-redux as a dependency rather than a peerDependency in your package.json. So you will potentially have two versions in the application in which the library is consumed, which causes the bug you described.
来源:https://stackoverflow.com/questions/65610678/could-not-find-react-redux-context-value-please-ensure-the-component-is-wrapped