Skip to content

Instantly share code, notes, and snippets.

@chrisirhc
Last active November 12, 2022 14:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chrisirhc/ae537cab089a887e3f0c5b57d57f07ab to your computer and use it in GitHub Desktop.
Save chrisirhc/ae537cab089a887e3f0c5b57d57f07ab to your computer and use it in GitHub Desktop.
Example using Profiler, keyboard events, and demonstrating effect of memoization. https://reactjs.org/docs/profiler.html
import { Profiler, useState, useMemo } from 'react';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event'
let msgs = [];
function pushMsg(id, phase, actualDuration, baseDuration, startTime, commitTime) {
msgs.push([id, phase])
}
function PushProfiler({id, children}) {
return (
<Profiler id={id} onRender={pushMsg}>
{children}
</Profiler>
);
}
beforeEach(() => {
msgs = [];
});
test('standard controlled input', async () => {
function App() {
const [val, setVal] = useState('')
return (
<div>
<PushProfiler id="Input">
<input value={val} onInput={(e) => setVal(e.target.value)}/>
</PushProfiler>
</div>
)
}
render(<PushProfiler id="App">
<App />
</PushProfiler>);
await userEvent.click(screen.getByRole('textbox'))
await userEvent.keyboard('fo') // translates to: f, o
expect(msgs).toEqual([
['Input', 'mount'],
['App', 'mount'],
['Input', 'update'],
['App', 'update'], // f
['Input', 'update'],
['App', 'update'] // o
])
});
test('Memoized children', async () => {
function Dummy() {
return (<PushProfiler id="Dummy"></PushProfiler>);
}
function App() {
const [val, setVal] = useState('')
const memoedChildren = useMemo(() => <Dummy/>, []);
return (
<div>
<PushProfiler id="Input">
<input value={val} onInput={(e) => setVal(e.target.value)}/>
</PushProfiler>
{memoedChildren}
</div>
)
}
render(<PushProfiler id="App">
<App />
</PushProfiler>);
await userEvent.click(screen.getByRole('textbox'))
await userEvent.keyboard('fo') // translates to: f, o
expect(msgs).toEqual([
['Input', 'mount'],
['Dummy', 'mount'],
['App', 'mount'],
['Input', 'update'],
['App', 'update'], // f
['Input', 'update'],
['App', 'update'] // o
])
});
test('Non-Memoized children', async () => {
function Dummy() {
return (<PushProfiler id="Dummy"></PushProfiler>);
}
function App() {
const [val, setVal] = useState('')
return (
<div>
<PushProfiler id="Input">
<input value={val} onInput={(e) => setVal(e.target.value)}/>
</PushProfiler>
<Dummy />
</div>
)
}
render(<PushProfiler id="App">
<App />
</PushProfiler>);
await userEvent.click(screen.getByRole('textbox'))
await userEvent.keyboard('fo') // translates to: f, o
expect(msgs).toEqual([
['Input', 'mount'],
['Dummy', 'mount'],
['App', 'mount'],
['Input', 'update'],
['Dummy', 'update'],
['App', 'update'], // f
['Input', 'update'],
['Dummy', 'update'],
['App', 'update'] // o
])
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment