`useInjectReducer` generates error in the console.
idMolotov opened this issue · 10 comments
Description
I've got error message in the browser console.
I've generate two components with npm run generate
command:
- NewPage
- SecondPage
with their own reducer's.
Now, when I switching from Home
page to the NewPage
and then to the SecondPage
I've got message:
Warning: Cannot update a component from inside the function body of a different component.
....
in this line:
useInjectReducer({ key: 'SecondPage', reducer: reducer });
Steps to reproduce
Steps to reproduce the behavior:
0) setup boilerplate 4.1
npm run generate
for two containers
- NewPage
- SecondPage
- add to
app/components/Header/index.tsx
<HeaderLink to="/new-page">
new page
</HeaderLink>
<HeaderLink to="/second-page">
second page
</HeaderLink>
Expected behavior
Need to have no warnings or errors from react in the console.
Versions
- React-Boilerplate:
"name": "react-boilerplate-typescript",
"version": "4.1.0",
"description": "A highly scalable, offline-first foundation with the best DX and a focus on performance and best practices",
"repository": {
"type": "git",
"url": "git://github.com/react-boilerplate/react-boilerplate-typescript.git"
},
"engines": {
"npm": ">=6.4.1",
"node": ">=10.13.0"
},
- Node/NPM:
node -v
v10.16.0
npm -v
6.9.0
- Browser:
Google Chrome
Version 84.0.4104.0 (Official Build) canary (64-bit)
If I add reducers init to app/configureStore.ts
const store = createStore(
createReducer({
newPage: NewPage,
secondPage: SecondPage,
}),
initialState,
enhancer,
) as InjectedStore;
and remove useInjectReducer({ key: 'newPage', reducer: reducer });
from corresponding components - everything looks ok.
Please, can you advice about using the reducer injectors.
Is this 'fix` is a correct workaround about this issue?
Can you show me the code of the pages you generate its hard to tell whats wrong judging by the error only.
nothing changed in the pages/containers after generation. So, I think they are exacatly the same as in the templates.
/*
*
* NewPage
*
*/
import React from 'react';
import { FormattedMessage } from 'react-intl';
import { useSelector, useDispatch } from 'react-redux';
import { createStructuredSelector } from 'reselect';
import { useInjectReducer, useInjectSaga } from 'redux-injectors';
import makeSelectNewPage from './selectors';
import reducer from './reducer';
import saga from './saga';
import messages from './messages';
const stateSelector = createStructuredSelector({
newPage: makeSelectNewPage(),
});
interface Props {}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function NewPage(props: Props) {
// useInjectReducer({ key: 'newPage', reducer: reducer });
useInjectSaga({ key: 'newPage', saga: saga });
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { newPage } = useSelector(stateSelector);
const dispatch = useDispatch(); // eslint-disable-line @typescript-eslint/no-unused-vars
return (
<div>
<FormattedMessage {...messages.header} />
</div>
);
}
export default NewPage;
useInjectReducer({ key: 'newPage', reducer: reducer });
is the newPage
key same for both of the generated pages?
no, other page is using own names
/*
*
* SecondPage
*
*/
import React from 'react';
import { FormattedMessage } from 'react-intl';
import { useSelector, useDispatch } from 'react-redux';
import { createStructuredSelector } from 'reselect';
import { useInjectReducer, useInjectSaga } from 'redux-injectors';
import makeSelectSecondPage from './selectors';
import reducer from './reducer';
import saga from './saga';
import messages from './messages';
const stateSelector = createStructuredSelector({
secondPage: makeSelectSecondPage(),
});
interface Props {}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function SecondPage(props: Props) {
useInjectReducer({ key: 'secondPage', reducer: reducer });
useInjectSaga({ key: 'secondPage', saga: saga });
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { secondPage } = useSelector(stateSelector);
const dispatch = useDispatch(); // eslint-disable-line @typescript-eslint/no-unused-vars
return (
<div>
<FormattedMessage {...messages.header} />
</div>
);
}
export default SecondPage;
Also, if I click in some other oder, I will got same error message for the second page.
Then I don't know why at this point. If you give a sample repo to download I can check if its a a bug you introduce or it comes from boilerplate's logic.
is this will helps you?
Repo:
https://github.com/idMolotov/rbt-examples
Commit with changes made on initial setup:
idMolotov/rbt-examples@a5b1371
Your selectors aren't selecting their slices but just return the root state object.
Go to your selectors.ts
in your new page container and make sure its like
const selectSecondPageDomain = (state: ApplicationRootState) =>
state.secondPage || initialState;
Notice the .secondPage
. So you work on your slice
Read more about the error here
I will also check if the generators can include this by default.