Conversation
npm Snapshot: PublishedGood news!! We've packaged up the latest commit from this PR (ef50623) and published it to npm. You Example: pnpm add @khanacademy/perseus@PR4126If you are working in Khan Academy's frontend, you can run the below command. ./dev/tools/bump_perseus_version.ts -t PR4126If you are working in Khan Academy's webapp, you can run the below command. ./dev/tools/bump_perseus_version.js -t PR4126Want another snapshot? Comment |
|
Size Change: +145 B (+0.03%) Total Size: 520 kB 📦 View Changed
ℹ️ View Unchanged
|
| // TODO(LEMS-3185): remove serializedState | ||
| blur(): void; | ||
| focus(): boolean | null | undefined; | ||
| props: any; |
There was a problem hiding this comment.
This isn't an API that Renderers need to implement, it's just part of React.
| const {renderer} = renderQuestion(itemWithMockWidget); | ||
|
|
||
| // Act | ||
| const node = renderer.getDOMNodeForPath(["mock-widget 1"]); |
There was a problem hiding this comment.
This is no longer an external API. It gets exercised when testing the APIs that use it.
| }); | ||
|
|
||
| // Act | ||
| const numHints = renderer.getNumHints(); |
There was a problem hiding this comment.
getNumHints didn't seem to be used by anything.
| </RenderStateRoot>, | ||
| <LoadingContext.Provider value={{onRendered}}> | ||
| <RenderStateRoot> | ||
| <ServerItemRenderer |
There was a problem hiding this comment.
The functional ServerItemRenderer wrapper was originally made to consumer LoadingContext. This PR stops exporting the unwrapped, class-based ServerItemRenderer. So to test this functionality we need to use the context provider (which is more realistic anyway).
| }); | ||
|
|
||
| // Act | ||
| act(() => renderer.focusPath(["mock-widget 1"])); |
There was a problem hiding this comment.
This is no longer an external API. It gets exercised when testing the APIs that use it.
| class Renderer | ||
| extends React.Component<Props, State> | ||
| implements GetPromptJSONInterface | ||
| implements RendererInterface, GetPromptJSONInterface |
There was a problem hiding this comment.
I just thought this made sense...
| React.useImperativeHandle( | ||
| ref, | ||
| () => { | ||
| const instance = (): ServerItemRenderer => { |
There was a problem hiding this comment.
A lot of this complexity can go away when we switch SIR entirely to a functional component.
| }; | ||
|
|
||
| return { | ||
| focus: () => instance().focus(), |
There was a problem hiding this comment.
Do you think the invariant is worthwhile over just doing this? (I guess I'm asking, do you think it's necessary to throw for unmounted SIRs?)
| focus: () => instance().focus(), | |
| focus: () => innerRef.current?.focus(), |
There was a problem hiding this comment.
I pushed back against the AI on this too. I think the reason it insists on doing this is type narrowing. The return type for getUserInput is UserInputMap, but doing innerRef.current?.getUserInput() changes it to UserInputMap | undefined. Using invariant narrows the type so innerRef.current can't be undefined.
I could do innerRef.current!.getUserInput() but at least with invariant we get a good error message if something goes horribly wrong. Open to push-back.
EDIT: and also this will go away when we switch SIR to a functional component.
There was a problem hiding this comment.
No, I don't have such a strong feeling about it. I see now what it's avoiding and that makes sense. I'll be happy when SIR is functional.
|
/snapshot |
… ServerItemRenderer to only allow explicitly declared imperative APIS
516c513 to
4c538ce
Compare
|
After making a ZND with the snapshot, there were some issues with infinite rerenders. I'm working on resolving these issues (see #4133) |
|
/snapshot |
…text' into server-item-renderer-imperative-handle
Summary:
I had a random idea this morning: what if we just wrap ServerItemRenderer (SIR) in a
forwardRefand useuseImperativeHandleto explicitly declare its external API? Turns out we were already wrapping SIR in aforwardRefso all I had to do was (1) stop exporting the inner SIR and (2) explicitly declare the API based on what we're actually using externally.Before the external API was something like (not including the methods starting with
_like_setCurrentFocus):Now it's:
And the methods starting with
_are not accessible at all.