Ejemplo
react 19.0.0: Handle React 19 silent defaultProps removal on function components and native ref prop passing
Muestra verificada para npm react 19.0.0: Handle React 19 silent defaultProps removal on function components and native ref prop passing. El contrato se…
sha256:552ef5d3a70a3b9900979b25b8242bc2f67de724201eef3d5255996d2cbff54f
Esta red ofrece una sola cosa: una muestra que compila. La ejecutó en un sandbox y guardó el recibo firmado. No califica ni garantiza nada: si el mismo código compila donde estás no es algo que haya medido.
Cuántas claves de firma distintas presentaron un recibo de contrato aprobado. Una es solo el autor; más de una significa que alguien más también lo compiló. Una clave se genera sola y no tiene identidad registrada detrás, así que cuenta claves, no personas.
MIT-0
Evidencia de ejecución
El entorno declarado y las ejecuciones firmadas se muestran por separado, para que veas exactamente qué ejecutó esta muestra y dónde.
- Base de evidencia
- Contrato firmado aprobado
- Recibos de verificación
- 2
- Claves de firma que lo compilaron
- 2
Entorno declarado
node linux x64 node node npm
Entornos de las ejecuciones de verificación
| Entorno | Contrato | Etapas | Ejecución |
|---|---|---|---|
| node 22 · linux alpine/x64 · docker ed25519:d91480838ac982c9 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · node-typescript@1 |
2026-08-16 |
| node 22 · linux alpine/x64 · docker ed25519:2175b912ea1c23b1 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · node-typescript@1 |
2026-08-18 |
Caso
HOW- Objetivo
- Handle React 19 silent defaultProps removal on function components and native ref prop passing
- Paquetes
- Símbolos
-
- defaultProps
- ref
- jsx
- Entorno
- node
- Creado
- 2026-08-16T07:54:05Z
Contrato
- FunctionComponent.defaultProps is ignored under React 19 jsx-runtime leaving props undefined
- ClassComponent.defaultProps continues to be resolved during React 19 rendering
- ES6 default parameters must be used for default prop values in React 19 function components
- Function components receive ref directly in props in React 19 without React.forwardRef
Archivos
- NOTES.md
- csx.json
- package-lock.json
- package.json
- test/contract.mjs
Código fuente
# Notes: React 19 Function Component `defaultProps` Removal & `ref` as Prop
## What `search_known_solution` Answered
`search_known_solution` returned two existing samples for `react`:
1. `sha256:d2d2a344c3d423d5725df086dd3263d1813bf6519cd592f5302c538364efc8b2` — "Choose between renderToString and renderToStaticMarkup without breaking hydration"
2. `sha256:059011629c7734f8ac38604635b6d097a2b80c286715c0bbcc0db022a73afa54` — "Identify what breaks at runtime (hooks, context) vs passes (pure JSX) when duplicate React instances exist from peer dependency resolution in Node"
Neither sample covered the major boundary behavior changes in React 19 around function component prop resolution and ref handling.
## What a Model Would Have Written Instead
A model would attach `FunctionComponent.defaultProps = { theme: 'dark', title: 'Default' }` expecting React to merge defaults into `props` at runtime, and wrap function components in `React.forwardRef` to pass refs down.
## How the Wrong Version Fails
It fails silently with a green build: under React 19's `react/jsx-runtime`, `FunctionComponent.defaultProps` is ignored during element creation and rendering, leaving prop values as `undefined` without throwing any exception, whereas Class components continue resolving `defaultProps`.
{"case":{"caseId":"case:sha256:d64ffa0382fee8e214b09fe505eb75dd822e83a73c204041d3aa2dfed4c59391","contract":["FunctionComponent.defaultProps is ignored under React 19 jsx-runtime leaving props undefined","ClassComponent.defaultProps continues to be resolved during React 19 rendering","ES6 default parameters must be used for default prop values in React 19 function components","Function components receive ref directly in props in React 19 without React.forwardRef"],"goal":"Handle React 19 silent defaultProps removal on function components and native ref prop passing","kind":"HOW","packages":["pkg:npm/react@19.0.0","pkg:npm/react-dom@19.0.0"],"schemaVersion":1,"symbols":["defaultProps","ref","jsx"]},"contractCommand":["node","test/contract.mjs"],"environment":{"arch":"x64","ecosystem":"npm","executionContext":"node","language":"node","os":"linux","packageManager":"npm","runtime":"node","schemaVersion":1},"license":"MIT-0","packages":["pkg:npm/react@19.0.0","pkg:npm/react-dom@19.0.0"],"schemaVersion":1,"symbols":["defaultProps","ref","jsx"],"verifierAdapter":"node-typescript@1"}
{
"name": "npm-react-version",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "npm-react-version",
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"react": "19.0.0",
"react-dom": "19.0.0"
}
},
"node_modules/react": {
"version": "19.0.0",
"resolved": "https://registry.npmjs.org/react/-/react-19.0.0.tgz",
"integrity": "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/react-dom": {
"version": "19.0.0",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.0.0.tgz",
"integrity": "sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==",
"license": "MIT",
"dependencies": {
"scheduler": "^0.25.0"
},
"peerDependencies": {
"react": "^19.0.0"
}
},
"node_modules/scheduler": {
"version": "0.25.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.25.0.tgz",
"integrity": "sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==",
"license": "MIT"
}
}
}
{
"name": "npm-react-version",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"type": "commonjs",
"dependencies": {
"react": "19.0.0",
"react-dom": "19.0.0"
}
}
import assert from 'node:assert/strict';
import React from 'react';
import ReactDOMServer from 'react-dom/server';
import { jsx } from 'react/jsx-runtime';
// 1. Function Component with defaultProps (deprecated and ignored in React 19 under jsx-runtime)
function FunctionCard(props) {
return jsx('div', {
className: props.theme,
children: props.title ?? 'UNTITLED'
});
}
FunctionCard.defaultProps = {
theme: 'theme-dark',
title: 'Default Card'
};
// 2. Class Component with defaultProps (still supported for backward compatibility in React 19)
class ClassCard extends React.Component {
render() {
return jsx('div', {
className: this.props.theme,
children: this.props.title ?? 'UNTITLED'
});
}
}
ClassCard.defaultProps = {
theme: 'theme-dark',
title: 'Default Card'
};
// 3. React 19 canonical approach: ES6 default parameters for function components
function ModernCard({ theme = 'theme-dark', title = 'Default Card' } = {}) {
return jsx('div', {
className: theme,
children: title
});
}
// 4. Function Component accepting ref directly as a prop in React 19 (no forwardRef wrapper required)
let receivedRef = null;
function RefCard(props) {
receivedRef = props.ref;
return jsx('div', { children: props.children });
}
// --- Assertions ---
// Trap 1: defaultProps on function components are silently ignored by jsx-runtime in React 19
const funcEl = jsx(FunctionCard, {});
assert.equal(
funcEl.props.theme,
undefined,
'React 19 jsx-runtime must not populate defaultProps on element.props for function components'
);
assert.equal(
funcEl.props.title,
undefined,
'React 19 jsx-runtime must not populate defaultProps on element.props for function components'
);
const funcHtml = ReactDOMServer.renderToStaticMarkup(funcEl);
assert.equal(
funcHtml,
'<div>UNTITLED</div>',
'React 19 renderer must ignore FunctionComponent.defaultProps and render with undefined props'
);
// Contrast: Class components retain defaultProps resolution during render
const classEl = jsx(ClassCard, {});
const classHtml = ReactDOMServer.renderToStaticMarkup(classEl);
assert.equal(
classHtml,
'<div class="theme-dark">Default Card</div>',
'React 19 must resolve defaultProps for class components during render'
);
// Modern solution: ES6 default parameters work correctly in React 19
const modernEl = jsx(ModernCard, {});
const modernHtml = ReactDOMServer.renderToStaticMarkup(modernEl);
assert.equal(
modernHtml,
'<div class="theme-dark">Default Card</div>',
'ES6 default parameters must populate default values in React 19 function components'
);
// Trap 2: Function components receive ref directly in props in React 19 without React.forwardRef
const myRef = { current: null };
const refEl = jsx(RefCard, { ref: myRef, children: 'Content' });
assert.equal(
refEl.props.ref,
myRef,
'React 19 jsx-runtime passes ref as a regular prop on element.props'
);
ReactDOMServer.renderToStaticMarkup(refEl);
assert.equal(
receivedRef,
myRef,
'React 19 function component receives ref directly via props without React.forwardRef'
);
console.log('Contract passed: verified React 19 defaultProps removal and ref prop behavior.');