Bug: React 19 Uncaught TypeError: Do not know how to serialize a BigInt
React version: 19
Steps To Reproduce
- Set props with bigint
import { useCallback, useState } from 'react';
interface ServiceItem {
name: string;
regionIds: bigint[];
}
interface MachineItem {
name: string;
services: ServiceItem[];
}
interface MachineItemProps {
machine: MachineItem;
}
function Machine(props: MachineItemProps) {
return (
<>
<p>{props.machine.name}</p>
{props.machine.services.map(service => (
<p key={service.name}>{service.name}</p>
))}
</>
);
}
export default function Page() {
const [update, setUpdate] = useState(0);
const [machine, setMachine] = useState(() => {
return {
name: 'machine1',
services: [
{
name: 'service1',
regionIds: [31321968590458880n]
}
]
};
});
const onClick = useCallback(() => {
setUpdate(update => ++update);
setMachine(() => {
return {
name: 'machine2',
services: [
{
name: 'service2',
regionIds: [31321968590458881n]
}
]
};
});
}, []);
return (
<>
<Machine machine={machine} />
<button onClick={onClick}>Update {update}</button>
</>
);
}
Link to code example:
https://codesandbox.io/p/sandbox/pedantic-shirley-cg3nf8
The current behavior
Throw exception
The expected behavior
Do not throw exception
The error occurs because React 19 is trying to serialize the bigint values when comparing props, but bigint cannot be serialized to JSON by default.
Convert the bigint values to strings, which is the most React-friendly approach:
interface ServiceItem {
name: string;
regionIds: string[]; // Changed from bigint[]
}
interface MachineItem {
name: string;
services: ServiceItem[];
}
interface MachineItemProps {
machine: MachineItem;
}
function Machine(props: MachineItemProps) {
return (
<>
<p>{props.machine.name}</p>
{props.machine.services.map(service => (
<p key={service.name}>{service.name}</p>
))}
</>
);
}
export default function Page() {
const [update, setUpdate] = useState(0);
const [machine, setMachine] = useState(() => {
return {
name: 'machine1',
services: [
{
name: 'service1',
regionIds: ['31321968590458880'] // String instead of bigint
}
]
};
});
const onClick = useCallback(() => {
setUpdate(update => ++update);
setMachine(() => {
return {
name: 'machine2',
services: [
{
name: 'service2',
regionIds: ['31321968590458881'] // String instead of bigint
}
]
};
});
}, []);
// ... rest of code
}
@hsparks-codes
I know this issue is caused by BigInt and only occurs in the development environment. Manually converting BigInt to a string is not an elegant solution. The best approach would be to fix this issue within React itself, rather than adding unnecessary cognitive load for developers. Moreover, this issue doesn’t exist in React 18.
Can this fix be merged? It's a significant issue for web3 apps where BigInts are frequently used.
@rcavalabs I have temporarily hacked it now, but the best solution is for the official internal handling of this issue.
if (__DEV__) {
Object.defineProperty(BigInt.prototype, 'toJSON', {
writable: false,
enumerable: true,
configurable: false,
value() {
return this.toString();
}
});
}