Open
Description
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
Activity