react-boilerplate-cra-template icon indicating copy to clipboard operation
react-boilerplate-cra-template copied to clipboard

useInjectReducer updates store, leading to warning "Cannot update a component (x) while rendering a different component..."

Open dungkhuc opened this issue 1 year ago • 6 comments

Description

We have 2 components, one is parent and one is child. Both components have its own slice. When the child component is rendered for the first time, a warning will be thrown in the console:

image

This is caused by useInjectReducer hook. My interpretation of the issue is that the hook make change to the store, affecting both the parent and the child component.

https://github.com/react-boilerplate/redux-injectors/blob/master/src/injectReducer.js#L69 image

This is briefly mentioned at the end in #54 , after it is closed.

This issue in react-redux seems to be related https://github.com/reduxjs/react-redux/issues/1640.

Steps to reproduce

  1. Create two components with separate injected reducers
  2. Nest one component in the other
  3. Start react app and navigate to route that render both component
  4. Check warning in the console.

Versions

  • react-boilerplate-cra-template: current
  • Node/NPM: 16.15.1
  • Browser: Chrome

dungkhuc avatar Jul 05 '22 15:07 dungkhuc

hmm, I have no solution within this repo atm. I already removed redux-injectors lib out of this repo and implemented them manually since that repo is dead. But, it will take a while till I release this version (winter probably. Have no time in summer).

Can-Sahin avatar Aug 02 '22 13:08 Can-Sahin

@Can-Sahin where is it available? How do I implement?

srivastavab avatar Dec 28 '22 06:12 srivastavab

Same issue. Waiting for a new release

trinvh avatar Dec 29 '22 16:12 trinvh

To others, I simply removed the injectors. This issue may cause some unexpected behaviors in the frontend.

dungkhuc avatar Jan 10 '23 08:01 dungkhuc

https://github.com/International-Slackline-Association/slackmap-ui

I have been working on this. You can see the new setup I made without injectors npm package. I don't have free time yet to update this repo, but if anybody is interested in solving it on their own then take a look. It's straightforward and explicit. Its in src/store.

By the way, it uses RTK Query instead Saga. Plus, it's really a web app working if you need some project references :)

Can-Sahin avatar Feb 13 '23 10:02 Can-Sahin

Just chiming in that this issue seems to occur when using RTK's dispatcher within a NextJS SSR block. I have a simple app skeleton that I am building out. It is using the SSR block to set the nav links into the state depending on the URL parameters. There is nowhere in the app's components where the store is changed other than with an onClick handler.

When I transition from the first page to the next this warning appears. The only way I can make it go away is by removing the NavLinks component which is using useAppSelect to get the nav links from my state/store.

Example SSR Block:

export const getServerSideProps = wrapper.getServerSideProps(
  (store) => async () => {
    // Set the nav first so we can access on the 404 page
    store.dispatch(
      setNavigation({
        isRestaurant: false,
        navLinks: genericNavLinks.links,
        isOpen: false,
      })
    );

    // Check we have page data
    const pageData = pages.find((page) => page.slug === "/");
    if (!pageData) return { notFound: true };
    return { props: { ...pageData } };
  }
);

The NavDrawer component (has the dispatch):

const NavDrawer: React.FC<NavDrawerProps> = ({ testId, id, style }) => {
  const { isOpen } = useAppSelector(selectNavigation);
  const dispatch = useAppDispatch();

  const handleNavClose: React.MouseEventHandler<HTMLButtonElement> = () =>
    dispatch(setNavigationOpen(false));

  return isOpen ? (
    <>
      <Underlay onClick={handleNavClose} isActive={true} />
      <div
        data-testid={testId}
        style={style}
        className={styles.wrapper}
        id={id}
      >
        <NavDrawerHeader />
        <NavLinks />
        <NavDrawerFooter />
      </div>
    </>
  ) : (
    <MobileNavOpenButton />
  );
};

The NavLinks component (If I remove the selector from here the warning goes away):


const NavLinks: React.FC<NavLinksProps> = ({ testId, id }) => {
  const { navLinks } = useAppSelector(selectNavigation);
  return (
    <div className={styles.wrapper}>
      <ul role="list" data-testid={testId} className={styles.list} id={id}>
        {navLinks.map((link) => (
          <NavLink key={link.id} link={link} />
        ))}
      </ul>
    </div>
  );
};

This has been doing my head in for a few days now, any advice?

PaulSinghDev avatar Apr 19 '23 06:04 PaulSinghDev