Skip to content

Using container on update hook causes React 16 errors to be printed #223

@yamadapc

Description

@yamadapc

When using container onUpdate hooks and setting state in them, react-sweet-state may call set state during render when the container props change.

This causes a warning on react 16 "Warning: Cannot update a component (Child) while rendering a different component".

The problem is caused by this section running on render:

    if (!shallowEqual(propsRef.current.next, propsRef.current.prev)) {
      containedStores.forEach(({ handlers }) => {
        handlers.onContainerUpdate?.(
          propsRef.current.next,
          propsRef.current.prev
        );
      });
    }

The following example reproduces the bug:

import "./styles.css";
import React, { useState } from "react";
import { createHook, createContainer, createStore } from "react-sweet-state";

export const hydrateContainer =
  () =>
  ({ setState }, { value }) => {
    setState({
      value,
    });
  };

const Store = createStore({
  actions: {},
  initialState: { value: 0 },
});
const Container = createContainer(Store, {
  onInit: hydrateContainer,
  onUpdate: hydrateContainer,
});

const useStore = createHook(Store);

function Child() {
  const [{ value: storeValue }] = useStore();
  return <div>storeValue: {storeValue}</div>;
}

export default function App() {
  const [value, setValue] = useState(0);

  return (
    <Container value={value}>
      value: {value}
      <Child />
      <button onClick={() => setValue((v) => v + 1)}>
        Click to bug out sweet state!
      </button>
    </Container>
  );
}

A sandbox reproduction is on - https://codesandbox.io/p/sandbox/cranky-dew-lvdhwv?file=%2Fsrc%2FApp.jsx%3A1%2C1-42%2C1

Metadata

Metadata

Assignees

No one assigned

    Labels

    duplicateThis issue or pull request already exists

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions