Cannot pass props object to React+typescript component


Sorry if this seems really obvious, but I’ve been trying to figure out for two days now. I’m writing a simple unit test in vitest that renders a component to screen and then calling screen.debug(). The test is

describe('Login unit tests', () => {
    it('renders to screen', () => {
        const loginProps = {
            handleSubmit: (e: MouseEvent<HTMLButtonElement>) => Promise.resolve(console.log('handleSubmit')),
            usernameProps: {
                value: "",
                placeholder: "Username",
                onChange: (e: ChangeEvent<HTMLInputElement>) => console.log('changeEvent'),
                type: "text"
            passwordProps: {
                value: "",
                placeholder: "Password",
                onChange: (e: ChangeEvent<HTMLInputElement>) => console.log('changeEvent'),
                type: "password" 
            isHidden: true,
        render(<Login {...loginProps} />);

The function definitions are just stand-ins with correct type, but would most likely be a vi.fn(). The component definition including interface of prop object is

interface LoginProps {
    handleSubmit: (e: MouseEvent<HTMLButtonElement>) => Promise<void>,
    usernameProps: InputProps,
    passwordProps: InputProps,
    isHidden: boolean,

const Login = ({
}: LoginProps) => {
    return (
        <div className="login-container">
            <div className="login-bounding-box">
                <div className="login-title">Login</div>
                <form className="login-form">
            <input {...usernameProps} />
            <input {...passwordProps} />
            <button type="submit" onClick={handleSubmit}>Login</button>
                <div className="error-msg" hidden={isHidden}>Username/password incorrect.</div>
                <div className="signup-msg">
                    Don't have an account? Sign up <Link to="/signup">here</Link>.

After running npm run test I get the following error:

TypeError: Cannot destructure property 'basename' of 'React__namespace.useContext(...)' as it is null.
 ❯ LinkWithRef node_modules/react-router-dom/index.tsx:427:11
 ❯ renderWithHooks node_modules/react-dom/cjs/react-dom.development.js:16305:18
 ❯ updateForwardRef node_modules/react-dom/cjs/react-dom.development.js:19226:20
 ❯ beginWork node_modules/react-dom/cjs/react-dom.development.js:21636:16
 ❯ beginWork$1 node_modules/react-dom/cjs/react-dom.development.js:27426:14
 ❯ performUnitOfWork node_modules/react-dom/cjs/react-dom.development.js:26560:12
 ❯ workLoopSync node_modules/react-dom/cjs/react-dom.development.js:26466:5
 ❯ renderRootSync node_modules/react-dom/cjs/react-dom.development.js:26434:7
 ❯ recoverFromConcurrentError node_modules/react-dom/cjs/react-dom.development.js:25850:20
 ❯ performConcurrentWorkOnRoot node_modules/react-dom/cjs/react-dom.development.js:25750:22

The interface for InputProps is

export default interface InputProps {
    value: string;
    placeholder: string | undefined;
    onChange: (e: ChangeEvent<HTMLInputElement>) => void;
    type: string;

I know the error is coming from the render(<Login />) line, but the error is cryptic and I’m not sure how to proceed. I assume there’s something wrong with how I’m passing in the props object to <Login /> but I can’t seem to figure out.

>Solution :

You’re probably wrapping a Router (like a BrowerRouter or MemoryRouter) somewhere in your app.
But for the tests, the component is rendered by itself, without the rest of the app.

In that case, it’s missing a Router, that React Router needs to find the basename property from its context.

Try rendering your test wrapped in a router, like so

import { BrowserRouter } from 'react-router-dom'
render(<BrowserRouter><Login {...loginProps} /></BrowserRouter>);

Leave a Reply Cancel reply