Knower
Auth
Debugging
React child error

Uncaught Error: Objects are not valid as a React child (found: object with keys {message}). If you meant to render a collection of children, use an array instead Error.

What I tried to do

I created dropdown menu to let users choose their role in signup form. Also, I tried to show an error message if error happens.


What I actually tried

OptionInput Component


I tried to show errorMessage inside of <p> tag when users did not choose any role option.

src/components/input/OptionInput.tsx
Copy

import React, { FC, SelectHTMLAttributes, forwardRef } from "react";
import "./style.OptionInput.scss";
interface OptionInputProp extends SelectHTMLAttributes<HTMLSelectElement> {
options: Array<string>;
errorMessage?: string | null;
}
const OptionInput: FC<OptionInputProp> = forwardRef<
HTMLSelectElement,
OptionInputProp
>(({ options, errorMessage, ...props }, ref) => {
return (
<div className="input__wrapper">
<select ref={ref} {...props}>
{options.map((value: string) => (
<option key={value} value={value}>
{value === "" ? "Please choose your role" : value}
</option>
))}
</select>
<p className="error-message">{errorMessage}</p>
</div>
);
});
export default OptionInput;

Signup Form


I sent options as array with string values as prop along with errorMessage altogether.

src/app/create-account/page.tsx
Copy

export default function CreateAccount(): JSX.Element {
return (
<section>
<div className="title__wrapper">
<h1 className="title">create account</h1>
</div>
<div className="form__wrapper">
<form
id="create-account"
onSubmit={handleSubmit(signUpFormSubmit, invalidSignUpSubmit)}
>
<div className="input-container">
<OptionInput
{...register("role")}
name="role"
options={["", "customer", "brand"]}
errorMessage={errors.role ? errors.role.message : null}
/>
</div>
{/* ... */}
</form>
</div>
</section>
);
}

Error that I got

I got an error in my browser console.


Error: Objects are not valid as a React child (found: object with keys {message}). If you meant to render a collection of children, use an array instead Error.

react_child_error Referrence: bobbyhadz.com

Package version


"dependencies": {
"@prisma/client": "^5.1.1",
"@types/node": "20.4.2",
"@types/react": "18.2.15",
"@types/react-dom": "18.2.7",
"eslint": "8.45.0",
"eslint-config-next": "13.4.11",
"next": "^13.4.16",
"ra-data-json-server": "^4.13.0",
"react": "18.2.0",
"react-admin": "4.10",
"react-dom": "18.2.0",
"react-hook-form": "^7.45.4",
"typescript": "5.1.6",
"yup": "^1.2.0"
},

Analysis

Error was literally saying that I could not send data of object type as prop.

I thought carefully and figured out that errorMessage inside of <p> tag would vary depending on option that users chose, which means errorMessage props would have multiple data. This occurred an error.

Solution

Thinking of UI meanwhile, I could only show an error by setting border-color as red color in <OptionInput /> component. That means, I did not even need to show errorMessage.

Therefore, I altered structure slightly that just showing whether input has an error, and if it does, then would set an extra className for error styling.

Checking whether error happened

I set className as .error in parent component <OptionInput /> when there was an error. If not, there would no className at all.

src/app/create-account/page.tsx
Copy

export default function CreateAccount(): JSX.Element {
return (
<section>
<div className="title__wrapper">
<h1 className="title">create account</h1>
</div>
<div className="form__wrapper">
<form
id="create-account"
onSubmit={handleSubmit(signUpFormSubmit, invalidSignUpSubmit)}
>
<div className="input-container">
<OptionInput
{...register("role")}
name="role"
options={["", "customer", "brand"]}
className={errors.role ? "error" : undefined}
/>
</div>
{/* ... */}
</form>
</div>
</section>
);
}

Error Styling

I deleted <p> tag and let users to choose options with <option> tag values.

Initial value was set to be empty string value("") when they did not choose anything, which triggers an error.

src/app/create-account/page.tsx
src/components/input/OptionInput.tsx
Copy

import React, { FC, SelectHTMLAttributes, forwardRef } from "react";
import "./style.OptionInput.scss";
interface OptionInputProp extends SelectHTMLAttributes<HTMLSelectElement> {
options: Array<string>;
error?: boolean;
}
const OptionInput: FC<OptionInputProp> = forwardRef<
HTMLSelectElement,
OptionInputProp
>(({ options, error, ...props }, ref) => {
return (
<div className="input__wrapper">
<select ref={ref} {...props}>
{options.map((value: string) => (
<option key={value} value={value}>
{value === "" ? "please choose your role" : value}
</option>
))}
</select>
</div>
);
});
export default OptionInput;

Checking whether error happened

I set className as .error in parent component <OptionInput /> when there was an error. If not, there would no className at all.

Error Styling

I deleted <p> tag and let users to choose options with <option> tag values.

Initial value was set to be empty string value("") when they did not choose anything, which triggers an error.

src/app/create-account/page.tsx
CopyExpandClose

export default function CreateAccount(): JSX.Element {
return (
<section>
<div className="title__wrapper">
<h1 className="title">create account</h1>
</div>
<div className="form__wrapper">
<form
id="create-account"
onSubmit={handleSubmit(signUpFormSubmit, invalidSignUpSubmit)}
>
<div className="input-container">
<OptionInput
{...register("role")}
name="role"
options={["", "customer", "brand"]}
className={errors.role ? "error" : undefined}
/>
</div>
{/* ... */}
</form>
</div>
</section>
);
}