This error occurs when attempting to render a bare number as a React child without wrapping it in proper JSX. While numbers are technically valid React children, this error typically indicates an unexpected rendering context where React cannot directly display a numeric value in your component.
React throws this error when you attempt to render a number in a context where it's not expected or properly formatted. While React does technically support numbers as valid children (they're rendered as strings), this specific error message typically appears in edge cases or type-checking scenarios. This error is less common than the "Objects are not valid" error, but it usually indicates a logic error in your component. For example, you might be accidentally trying to render a numeric state value or calculation result directly when it should be converted to a string, wrapped in an element, or used within a formatted template. The error emphasizes that even though React can technically display numbers, there's something wrong with how you're rendering them in this particular context. It could be type validation in TypeScript, unexpected prop passing, or an unintended numeric value appearing in JSX where a string is expected.
Check the React error stack trace to identify which component and line is causing the issue:
Error: Numbers are not valid as a React child (found: number)
at Component (App.js:12)Look for JSX expressions that contain numbers:
// ❌ This might cause the error
function Counter() {
const count = 5;
return <div>{count}</div>;
}Inspect your component code for places where you're rendering numeric values directly.
Use String() constructor or .toString() to convert numbers to strings:
Before (potential issue):
function Counter({ count }) {
return <p>Items: {count}</p>;
}After (converted to string):
function Counter({ count }) {
return <p>Items: {String(count)}</p>;
// Or use .toString()
// return <p>Items: {count.toString()}</p>;
}This explicitly converts the number to a string representation.
Backticks automatically convert numbers to strings:
Before:
function Display({ id, count }) {
return <div>{id} - {count} items</div>;
}After (with template literals):
function Display({ id, count }) {
return <div>{`${id} - ${count} items`}</div>;
// Or keep individual expressions as they're still valid
return <div>ID: {id}, Count: {count}</div>;
}Template literals can handle both string and numeric values seamlessly.
When rendering calculations, convert results to strings or use template literals:
Before (calculation result as number):
function Calculator({ a, b }) {
return <div>Sum: {a + b}</div>;
// Or
return <div>{a * b}</div>;
}After (proper rendering):
function Calculator({ a, b }) {
return <div>Sum: {String(a + b)}</div>;
// Or
return <div>{(a * b).toString()}</div>;
// Or better with template literals
return <div>Sum: `${a + b}`</div>;
}These approaches ensure numeric calculations display correctly.
When mapping arrays of numbers, wrap them in JSX or convert to strings:
Before (causes error):
function NumberList({ numbers }) {
return (
<ul>
{numbers.map((num, index) => (
<li key={index}>{num}</li>
))}
</ul>
);
}After (wrapped in JSX):
function NumberList({ numbers }) {
return (
<ul>
{numbers.map((num, index) => (
<li key={index}>Number: {String(num)}</li>
))}
</ul>
);
}Always wrap or convert numeric values in mapped arrays.
Timestamps and IDs often need formatting before display:
Before (raw number):
function EventCard({ event }) {
return (
<div>
<h3>{event.title}</h3>
<p>Created: {event.timestamp}</p>
</div>
);
}After (formatted):
function EventCard({ event }) {
const formattedDate = new Date(event.timestamp).toLocaleDateString();
return (
<div>
<h3>{event.title}</h3>
<p>Created: {formattedDate}</p>
</div>
);
}Use proper formatting functions for numeric timestamps and IDs.
Ensure conditional expressions don't return bare numbers:
Before (returns number):
function Display({ count }) {
return (
<div>
{count > 0 ? count : null}
</div>
);
}After (properly formatted):
function Display({ count }) {
return (
<div>
{count > 0 ? `Count: ${count}` : 'No items'}
</div>
);
}Make sure your ternary operators and conditional returns produce strings or JSX, not bare numbers.
Use TypeScript to catch numeric rendering issues at compile time:
TypeScript component definition:
interface Props {
count: number;
label: string;
}
function Counter({ count, label }: Props) {
return <p>{label}: {String(count)}</p>;
}Type helper for rendereable children:
type RenderableChild = string | number | React.ReactNode;
function Display({ value }: { value: RenderableChild }) {
return <div>{value}</div>;
}TypeScript helps enforce proper type conversions for numeric values.
React.ReactNode type: While React.ReactNode includes numbers as a valid type, practical rendering often requires explicit conversion. The type system says numbers are valid, but this error indicates a context where the number isn't being handled correctly.
Performance consideration: Converting numbers to strings with String() is extremely fast and negligible for performance. Don't worry about the overhead of explicit conversion - it's better to be explicit than risk rendering issues.
Why this error matters: This error is rare because React actually does support numbers as children. When you encounter it, it usually signals a mistake in your component logic - perhaps you meant to render a string, or you forgot to format/convert the number. Always investigate the root cause rather than just adding String() everywhere.
Internationalization (i18n): When displaying numbers that vary by locale (currency, percentages, dates), use proper formatting libraries:
function Price({ amount, currency = 'USD' }) {
const formatted = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: currency,
}).format(amount);
return <p>Price: {formatted}</p>;
}React children validation: Understand that React validates children types. While numbers pass validation, this error suggests you're in an edge case where React's type checking is stricter. Use it as a signal to review your component's logic.
Console filtering: During development, if you see this error repeatedly, add a boundary component to catch and log the specific values causing the issue for debugging:
function SafeDisplay({ value }) {
if (typeof value === 'number') {
console.warn('Rendering number:', value);
return <span>{String(value)}</span>;
}
return <>{value}</>;
}React Hook useCallback has a missing dependency: 'variable'. Either include it or remove the dependency array react-hooks/exhaustive-deps
React Hook useCallback has a missing dependency
Cannot use private fields in class components without TS support
Cannot use private fields in class components without TS support
Cannot destructure property 'xxx' of 'undefined'
Cannot destructure property of undefined when accessing props
useNavigate() may be used only in the context of a <Router> component.
useNavigate() may be used only in the context of a Router component
Cannot find module or its corresponding type declarations
How to fix "Cannot find module or type declarations" in Vite