Skip to content

Commit 9fe5904

Browse files
committed
Potential repro for possible bug w #26763
1 parent 0fba3ec commit 9fe5904

File tree

1 file changed

+94
-0
lines changed

1 file changed

+94
-0
lines changed

packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.js

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,4 +121,98 @@ describe('ReactTestRenderer', () => {
121121
expect(root.toJSON().children).toEqual(['dynamic']);
122122
});
123123
});
124+
125+
it('repro for bug with useEffect synchronization', () => {
126+
const ListContext = React.createContext(null);
127+
const SelectionContext = React.createContext(null);
128+
129+
function List(props) {
130+
const [expanded, setExpanded] = React.useState(new Set());
131+
const listContext = React.useMemo(() => {
132+
return {
133+
onExpanded(id) {
134+
setExpanded(prevExpanded => new Set([...prevExpanded, id]));
135+
},
136+
};
137+
}, []);
138+
const selectionContext = React.useMemo(() => {
139+
return {
140+
expanded,
141+
};
142+
}, [expanded]);
143+
return (
144+
<ListContext.Provider value={listContext}>
145+
<SelectionContext.Provider value={selectionContext}>
146+
{props.children}
147+
</SelectionContext.Provider>
148+
</ListContext.Provider>
149+
);
150+
}
151+
152+
function ListItem(props) {
153+
const {onExpanded} = React.useContext(ListContext);
154+
const selectionContext = React.useContext(SelectionContext);
155+
const isExpanded = selectionContext.expanded.has(props.id);
156+
const didInitiallyExpand = React.useRef(false);
157+
const shouldInitiallyExpand =
158+
props.initiallyExpanded && didInitiallyExpand.current === false;
159+
const id = props.id;
160+
161+
React.useEffect(() => {
162+
if (shouldInitiallyExpand) {
163+
didInitiallyExpand.current = true;
164+
onExpanded(id);
165+
}
166+
}, [shouldInitiallyExpand, onExpanded, id]);
167+
168+
const expand = React.useCallback(() => {
169+
onExpanded(id);
170+
}, [id]);
171+
172+
return isExpanded ? (
173+
<div>{props.children}</div>
174+
) : (
175+
<div onClick={expand}>Expand</div>
176+
);
177+
}
178+
179+
function Component() {
180+
return (
181+
<List>
182+
<ListItem id="1" initiallyExpanded={true}>
183+
Item 1
184+
</ListItem>
185+
<ListItem id="2" initiallyExpanded={true}>
186+
Item 2
187+
</ListItem>
188+
<ListItem id="3" initiallyExpanded={false}>
189+
Item 3
190+
</ListItem>
191+
</List>
192+
);
193+
}
194+
195+
let renderer;
196+
ReactTestRenderer.act(() => {
197+
renderer = ReactTestRenderer.create(<Component />);
198+
});
199+
const serialized = renderer.toJSON();
200+
expect(serialized).toMatchInlineSnapshot(`
201+
[
202+
<div
203+
onClick={[Function]}
204+
>
205+
Expand
206+
</div>,
207+
<div>
208+
Item 2
209+
</div>,
210+
<div
211+
onClick={[Function]}
212+
>
213+
Expand
214+
</div>,
215+
]
216+
`);
217+
});
124218
});

0 commit comments

Comments
 (0)