-
Notifications
You must be signed in to change notification settings - Fork 5
VIDCS-3681: Bump up React version #154
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@@ -17,7 +17,7 @@ import DeviceStore from '../../../utils/DeviceStore'; | |||
const usePublisherOptions = (): PublisherProperties | null => { | |||
const { user } = useUserContext(); | |||
const [publisherOptions, setPublisherOptions] = useState<PublisherProperties | null>(null); | |||
const deviceStoreRef = useRef<DeviceStore>(); | |||
const deviceStoreRef = useRef<DeviceStore | null>(null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: this was changed in a few places. it is enforced in React 19
expect((outputDevicesElement.firstChild as HTMLOptionElement).selected).toBe(true); | ||
expect((outputDevicesElement.firstChild as Element).classList.contains('Mui-selected')).toBe( | ||
true | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: this was returning undefined
after an update and needed to be changed on how we access the selected
property.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we be more specific than Element
? Should this be a div
, an li
, span
, or is it unknown so an HTMLElement
?
@@ -22,16 +22,23 @@ describe('GoodBye', () => { | |||
}); | |||
|
|||
it('should render', () => { | |||
render(<GoodBye />, { wrapper: BrowserRouter }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: wrapper: BrowserRouter
is no longer supported. the change is fairly simple though, just had to directly wrap the Goodbye
component with BrowserRouter
frontend/vite.config.ts
Outdated
react({ | ||
babel: { | ||
plugins: isTest | ||
? [] // Disable babel-plugin-react-compiler in test environment | ||
: [['babel-plugin-react-compiler', { target: '19' }]], | ||
}, | ||
}), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: this was added because the React Compiler was breaking the tests by injecting things like UseMemoCache
that are undefined
in the vitest
environment.
target
set to 19
refers to the React version.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this a recommended workaround? Are there more people dealing with this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copilot suggested this workaround. there isn't a whole lot of people dealing with this quite yet since it's a fairly new plugin
frontend/package.json
Outdated
"@types/react-router-dom": "^5.3.3", | ||
"@types/ua-parser-js": "^0.7.39", | ||
"@types/uuid": "^9.0.8", | ||
"@vitest/coverage-v8": "^1.3.0", | ||
"@vitest/ui": "^1.3", | ||
"babel-plugin-react-compiler": "19.1.0-rc.1", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: please do not be scared that the name of the React Compiler starts with babel-plugin
. While it works in babel, it is also fully supported with vite
- as you can see, no babel.config
files have been introduced and it is all handled within vite.config.ts
@@ -1,6 +1,6 @@ | |||
import { act, renderHook } from '@testing-library/react'; | |||
import { beforeEach, describe, expect, it, Mock, Mocked, vi } from 'vitest'; | |||
import { MutableRefObject } from 'react'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: MutableRefObject
has been discontinued in React 19. SonarCloud is very unhappy about keeping this even though it is not currently a breaking change. This has been replaced with RefObject
s. All other changes related to MutableRefObject
are for the same reason.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To confirm, there's no way to disambiguate between mutable and immutable ref objects?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
correct, they're all refobject
s now and it is mutable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR upgrades the React version from 18 to 19 and introduces the React Compiler via a Babel plugin, while also refactoring several type definitions by replacing MutableRefObject with RefObject in both production code and tests. Additionally, tests are updated to properly wrap components with BrowserRouter for rendering.
Reviewed Changes
Copilot reviewed 15 out of 16 changed files in this pull request and generated no comments.
Show a summary per file
File | Description |
---|---|
frontend/vite.config.ts | Added "isTest" flag and Babel plugin configuration for React Compiler. |
frontend/src/utils/helpers/getLayoutBoxes/getLayoutBoxes.ts | Replaced MutableRefObject with RefObject in ref type. |
frontend/src/utils/helpers/getLayoutBoxes/getLayoutBoxes.spec.ts | Updated ref type in tests accordingly. |
frontend/src/pages/UnsupportedBrowserPage/UnsupportedBrowserPage.spec.tsx | Wrapped component in BrowserRouter for improved rendering in tests. |
frontend/src/pages/GoodBye/GoodBye.spec.tsx | Wrapped GoodBye in BrowserRouter and updated expectations for UI. |
frontend/src/hooks/useToolbarButtons.tsx | Updated ref types to RefObject. |
frontend/src/hooks/useElementDimensions.tsx | Updated ref type and initialized the ResizeObserver ref explicitly. |
frontend/src/hooks/useChat.tsx | Changed default value logic using the nullish coalescing operator. |
frontend/src/hooks/useArchives.tsx | Initialized the pollingIntervalRef with undefined. |
frontend/src/hooks/tests/useChat.spec.tsx | Updated ref type in tests. |
frontend/src/components/MeetingRoom/DeviceSettingsMenu/DeviceSettingsMenu.tsx | Adjusted ref type in props for anchorRef to support null value. |
frontend/src/components/MeetingRoom/DeviceSettingsMenu/DeviceSettingsMenu.spec.tsx | Updated tests to check for CSS class "Mui-selected" instead of HTML select state. |
frontend/src/components/MeetingRoom/DeviceControlButton/DeviceControlButton.tsx | Adjusted ref type in DeviceControlButton for anchorRef. |
frontend/src/Context/PublisherProvider/usePublisherOptions/usePublisherOptions.tsx | Changed deviceStoreRef type to include null initially. |
Files not reviewed (1)
- frontend/package.json: Language not supported
Comments suppressed due to low confidence (1)
frontend/src/components/MeetingRoom/DeviceSettingsMenu/DeviceSettingsMenu.spec.tsx:115
- [nitpick] If this assertion is synchronous, consider removing the 'await' keyword to improve test clarity and consistency.
await expect((outputDevicesElement.firstChild as Element).classList.contains('Mui-selected')).toBe(true);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice one, good to keep up to date 👍 Left a couple q's
@@ -40,7 +40,7 @@ const HelperText = ({ | |||
}; | |||
|
|||
return ( | |||
<Box display="flex" justifyContent="space-between" width="100%"> | |||
<Box component="span" display="flex" justifyContent="space-between" width="100%"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was this a span before? I think technically spans aren't meant to contain child elements
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this was just a <p>
before with some <div>
s inside of it and it was failing with:
In HTML, <div> cannot be a descendant of <p>.
This will cause a hydration error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be okay. The component will be a span containing more spans.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The semantics are odd. Box
implies "block level" element. By contrast, span
implies "inlined" elements, like Mike mentioned.
Do we need to add component="span"
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes I think we need to add that component="span"
here since this HelperText
component is used inside of another component, FeedbackForm.
the FeedbackForm
consists out of a bunch of <p>
s and nesting a <div>
inside of it causes a hydration error (see comment above). That's why we need to set Box
components to span
so rendering looks like this:
<p>
<span>...</span>
<span>...</span>
</p>
<p>
....
</p>
frontend/vite.config.ts
Outdated
react({ | ||
babel: { | ||
plugins: isTest | ||
? [] // Disable babel-plugin-react-compiler in test environment | ||
: [['babel-plugin-react-compiler', { target: '19' }]], | ||
}, | ||
}), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this a recommended workaround? Are there more people dealing with this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good so far! Just have a few comments/questions. Let me know what you think!
frontend/src/components/MeetingRoom/DeviceSettingsMenu/DeviceSettingsMenu.spec.tsx
Outdated
Show resolved
Hide resolved
expect((outputDevicesElement.firstChild as HTMLOptionElement).selected).toBe(true); | ||
expect((outputDevicesElement.firstChild as Element).classList.contains('Mui-selected')).toBe( | ||
true | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we be more specific than Element
? Should this be a div
, an li
, span
, or is it unknown so an HTMLElement
?
@@ -120,7 +123,9 @@ describe('DeviceSettingsMenu Component', () => { | |||
await act(() => (outputDevicesElement.children[2] as HTMLOptionElement).click?.()); | |||
|
|||
expect(mockSetAudioOutputDevice).toHaveBeenCalledWith(audioOutputDevices[2].deviceId); | |||
await expect((outputDevicesElement.children[2] as HTMLOptionElement).selected).toBe(true); | |||
expect((outputDevicesElement.children[2] as Element).classList.contains('Mui-selected')).toBe( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to check the visual indicator we use is present for this output device? I'm not a big fan of checking the presence of a class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see a particular issue with checking for a class. I will add an extra expect to check that the following element is not currently selected, though, to be extra certain
@@ -40,7 +40,7 @@ const HelperText = ({ | |||
}; | |||
|
|||
return ( | |||
<Box display="flex" justifyContent="space-between" width="100%"> | |||
<Box component="span" display="flex" justifyContent="space-between" width="100%"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be okay. The component will be a span containing more spans.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM Great job!
@behei-vonage, some nice initiative here 💪 That said, some questions/comments:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! 💪
That said, left some questions/comments. Thanks! 🙏
"@testing-library/jest-dom": "^6.6.3", | ||
"@testing-library/react": "^16.3.0", | ||
"@testing-library/user-event": "^14.6.1", | ||
"@vitejs/plugin-react": "^4.4.1", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do these need to be upgraded as well? If so, it's because the new version of React requires this, yes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, react 19 requires these packages to be upgraded
@@ -1,6 +1,6 @@ | |||
import { act, queryByText, render, screen, waitFor } from '@testing-library/react'; | |||
import { describe, beforeEach, it, Mock, vi, expect, afterAll } from 'vitest'; | |||
import { MutableRefObject } from 'react'; | |||
import { RefObject } from 'react'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For React 19, all RefObject
s are implicitly mutable now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that is correct, mutablerefobject has been deprecated and it's all on refobject now
frontend/src/components/MeetingRoom/DeviceSettingsMenu/DeviceSettingsMenu.spec.tsx
Outdated
Show resolved
Hide resolved
@@ -40,7 +40,7 @@ const HelperText = ({ | |||
}; | |||
|
|||
return ( | |||
<Box display="flex" justifyContent="space-between" width="100%"> | |||
<Box component="span" display="flex" justifyContent="space-between" width="100%"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The semantics are odd. Box
implies "block level" element. By contrast, span
implies "inlined" elements, like Mike mentioned.
Do we need to add component="span"
?
@@ -1,6 +1,6 @@ | |||
import { act, renderHook } from '@testing-library/react'; | |||
import { beforeEach, describe, expect, it, Mock, Mocked, vi } from 'vitest'; | |||
import { MutableRefObject } from 'react'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To confirm, there's no way to disambiguate between mutable and immutable ref objects?
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! 💪 🚀
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM Great job!
Tested LGTM!! 🚀 |
What is this PR doing?
This PR bumps up version of react used in the project from 18 to 19.
How should this be manually tested?
A few things need to be tested as a part of this PR.
Given that there is a version update of the framework that we use, it'd be great to check that the basic functionality works as expected - multiple people in the meeting room, participant list/chat/report issue functionality works, changing audio/video sources works etc.
CI passes
What are the relevant tickets?
A maintainer will add this ticket number.
Resolves VIDCS-3681
Checklist
[ ] Branch is based on
develop
(notmain
).[ ] Resolves a
Known Issue
.[ ] If yes, did you remove the item from the
docs/KNOWN_ISSUES.md
?[ ] Resolves an item reported in
Issues
.If yes, which issue? Issue Number?