I have a React on Rails app and I am getting a failure to render due to could not find react-redux context value; please ensure the component is wrapped in a <Provider>
could not find react-redux context value; please ensure the component is wrapped in a <Provider>
.
Component (inner content and imports omitted for brevity):
const MyPage = ({ reduxData, payloads }) => {
const store = useReduxStore(reduxData);
const jads = new JsonApiDataStore();
const users = jads.sync(payloads.users);
//custom selector
const pathName = useSelector(selectPathName);
return (
<Provider store={store}>
<div>
{users.map((user) => (
<li key={user.id} />
))}
</div>
<div>{pathname}</div>
</Provider>
);
};
MyPage.propTypes = {
reduxData: PropTypes.shape(ReduxData).isRequired,
payloads: PropTypes.shape({
users: PropTypes.shape(Payload).isRequired,
}).isRequired,
};
export default MyPage;
view(index.html.erb for this directory/controller)
<% content_for :title, "MyPage" %>
<% page = react_component_hash(
"MyPage",
props: {
reduxData: redux_data,
payloads: {
users: serialize(
@users,
UserSerializer,
),
}
},
prerender: true
) %>
<% content_for :page_styles, page["componentCss"] %>
<%= page["componentHtml"] %>
Controller Route:
def index
@users = User.all
render layout: "react"
end
in my application controller:
def redux_data
{
data: {
pathName: request.path
},
currentUser: serialize(current_user, CurrentUserSerializer, include: %w[company])
}
end
helper_method :redux_data
(This works on other pages with a similar setup).
What am I missing?
The issue was that I was trying to use a selector in the same component that provided the Provider
/ context, essentially before the context was provided. Instead, I needed to use selectors only in child components / within the main component that has the <Provider />
wrapper so that the selector has access to the context.
In my case:
child component:
const ChildComponent = () => {
const pathName = useSelector(selectPathName);
return (
<div>{pathname}</div>
);
};
export default ChildComponent;
parent component:
const MyPage = ({ reduxData, payloads }) => {
const store = useReduxStore(reduxData);
const jads = new JsonApiDataStore();
const users = jads.sync(payloads.users);
return (
<Provider store={store}>
<div>
{users.map((user) => (
<li key={user.id} />
))}
</div>
<ChildComponent />
</Provider>
);
};
MyPage.propTypes = {
reduxData: PropTypes.shape(ReduxData).isRequired,
payloads: PropTypes.shape({
users: PropTypes.shape(Payload).isRequired,
}).isRequired,
};
export default MyPage;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.