-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Labels
bugSomething isn't workingSomething isn't working
Description
Version
Latest development (@main)
Module resolution
ESM: import { createChainOfResponsibility } from "react-chain-of-responsibility"
Bundler
Others or unrelated
Environment
Others or unrelated
Test case
(not tested this)
/** @jest-environment jsdom */
/// <reference types="@types/jest" />
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import React, { useState } from 'react';
import { RCoRTree } from '../components/RCoRTree'; // Adjust path if necessary
describe('React Chain of Responsibility Bug Reproduction', () => {
test('StatefulCounter loses internal state and is recreated when RCoR request changes', async () => {
const TestWrapper = () => {
const [variant, setVariant] = useState<'blue' | 'green' | 'purple'>('blue');
const [rcorCount, setRcorCount] = useState(0);
return (
<div>
<button onClick={() => setVariant('green')}>Change Variant to Green</button>
<RCoRTree variant={variant} onCountChange={setRcorCount} />
<div data-testid="rcor-external-count">External RCoR Count: {rcorCount}</div>
</div>
);
};
render(<TestWrapper />);
// 1. Verify initial state and increment the RCoR counter
const initialRCoRCounterDisplay = screen.getByText(/Counter \(blue\)/i);
const initialRCoRCounterContainer = initialRCoRCounterDisplay.closest('.p-6');
const initialRCoRIncrementButton = initialRCoRCounterContainer?.querySelector('[aria-label="Increment"]');
expect(initialRCoRIncrementButton).toBeInTheDocument();
expect(initialRCoRCounterContainer).toHaveTextContent('0'); // Initial count is 0
// Get initial instance ID
const initialInstanceIdMatch = initialRCoRCounterContainer?.textContent?.match(/Instance #(\d+)/);
const initialInstanceId = initialInstanceIdMatch ? parseInt(initialInstanceIdMatch[1], 10) : null;
expect(initialInstanceId).not.toBeNull();
// Increment the counter multiple times
fireEvent.click(initialRCoRIncrementButton!);
fireEvent.click(initialRCoRIncrementButton!);
fireEvent.click(initialRCoRIncrementButton!);
// Wait for the displayed count to update to 3
await waitFor(() => {
expect(initialRCoRCounterContainer).toHaveTextContent('3');
});
// Also check the external state update
expect(screen.getByTestId('rcor-external-count')).toHaveTextContent('External RCoR Count: 3');
// 2. Trigger a variant change
const changeVariantButton = screen.getByText('Change Variant to Green');
fireEvent.click(changeVariantButton);
// 3. Verify state loss: The RCoR counter should reset to 0
// The label will change to "Counter (green)", so find the new counter display
const newRCoRCounterDisplay = screen.getByText(/Counter \(green\)/i);
const newRCoRCounterContainer = newRCoRCounterDisplay.closest('.p-6');
await waitFor(() => {
// The count should be 0 again, indicating state loss
expect(newRCoRCounterContainer).toHaveTextContent('0');
});
// Also check the external state update
expect(screen.getByTestId('rcor-external-count')).toHaveTextContent('External RCoR Count: 0');
// 4. Verify instance ID changes, confirming recreation
const newInstanceIdMatch = newRCoRCounterContainer?.textContent?.match(/Instance #(\d+)/);
const newInstanceId = newInstanceIdMatch ? parseInt(newInstanceIdMatch[1], 10) : null;
expect(newInstanceId).not.toBeNull();
expect(newInstanceId).not.toBe(initialInstanceId); // This confirms recreation
});
});
Coding sandbox URL
https://stackblitz.com/edit/sb1-hks9ug7t?file=src%2Fcomponents%2FReproDemo.tsx
Console errors
No errors
Screenshots
Screenshot right after variant got changed (RCoR tree counter was equal to the left tree):
Additional context
It's worsen without memo
. Without memo the component being re-created basically on every re-render.
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working