I have this code on my index.js
file in my ReactJS project and I want the redux's <Provider>
tag to wrap them up so that they can all access the same store,
The question is, how can I do that?
ReactDOM.render(<Header />, document.getElementById('header'));
ReactDOM.render(<App />, document.getElementById('root'));
ReactDOM.render(<Footer />, document.getElementById('footer'));
Well, if the store
is the same, then you can simply apply the <Provider>
to all pieces and they will all use the same Redux store. The Provider
is not mandatory to be unique, just the store
. Something like this:
const store = createStore(...); // or any valid Redux store declaration or import
ReactDOM.render(<Provider store={store}><Header /></Provider>, document.getElementById('header'));
ReactDOM.render(<Provider store={store}><App /></Provider>, document.getElementById('root'));
ReactDOM.render(<Provider store={store}><Footer /></Provider>, document.getElementById('footer'));
As another answer already suggests, this can be achieved by using same store in Redux provider. Since Redux isn't tied to React component hierarchy, connected components don't necessarily should have a common parent:
ReactDOM.render(
<Provider store={store}><Header /></Provider>,
document.getElementById('header')
);
ReactDOM.render(
<Provider store={store}><App /></Provider>,
document.getElementById('root')
);
ReactDOM.render(
<Provider store={store}><Footer /></Provider>,
document.getElementById('footer')
);
Another option that isn't specific to Redux but can also be used with any React application that has several root components is to use portals for these components, as shown in this answer:
const Page = props => (
<Provider store={store}>
{ReactDOM.createPortal(<Header/>, document.getElementById('header'))}
{ReactDOM.createPortal(<App/>, document.getElementById('root'))}
{ReactDOM.createPortal(<Footer/>, document.getElementById('footer'))}
</Provider>
);
ReactDOM.render(<Page/>, document.getElementById('page'));
Where <div id="page"></div>
is placeholder element that exists in HTML body to mount the application and doesn't have to be a parent to header, etc. elements.
This option can be used with React context API Provider
or page component state
as well.
Is there a reason that you need to target three html elements? The standard practice here would be to just target root
and handle the rest in your React application, like below:
In index.js
:
const store = createStore(...);
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>, document.getElementById('root'));
In App.js
:
export default = () =>
<Header />
<Body />
<Footer />
Your entire HTML body would look like this (recommended approach by Facebook's create-react-app):
<body>
<noscript>JavaScript must be enabled to run this application.</noscript>
<div id="root"></div>
</body>