Uh oh!
There was an error while loading. Please reload this page.
feat: add React 19 replace default props transform - #331
Conversation
thanks @amirabbas-gh (and @mohebifar)! @rickhanlonii, this is the first of many PRs from Codemod. appreciate your review! |
23b6272 to
dc9175fComparedc9175f to
0d7dc9fCompare
eps1lon
left a comment
There was a problem hiding this comment.
How does this handle more complex types like objects? One issue with migrating from .defaultProps to function default parameters is that creating an object in the default parameter would invalidate memoization too often.
E.g.
functionComponent({ options ={}}){}is not equivalent to
functionComponent({ options }){}Component.defaultProps={options: {}}you'd have to to hoist those values out e.g.
constdefaultOptions={}functionComponent({ options =defaultOptions}){}| const C = (props) => { | ||
| return <>{props.text}</>; | ||
| }; |
There was a problem hiding this comment.
This no longer sets props.text by default. The codemod should opt out here with a message (or insert a comment) that it couldn't handle this case.
There was a problem hiding this comment.
@amirabbas-gh Can we do something like this?
Before:
constC=(props)=>{constsomeValue=props.text;const{ text }=props;return<>{props.text}</>;};After:
constC=(props)=>{constprops_textWithDefault=typeofprops.text==='undefined' ? 'test' : props.text;constsomeValue=props_textWithDefault;const{ text =props_textWithDefault}=props;return<>{props_textWithDefault}</>;};There was a problem hiding this comment.
It won't be able to handle the case of computed member expressions, which is ok, and perhaps we should just leave a note/comment for such cases:
constC=(props)=>{constkey=cond ? "text" : "title";return<>{/* Codemod: Please make sure this is not affected by removal of defaultProps */}{props[key]}</>;};There was a problem hiding this comment.
@eps1lon
I have another proposal:
| constC=(props)=>{ | |
| return<>{props.text}</>; | |
| }; | |
| constC=(props)=>{ | |
| props={...props,text: typeofprops.text==='undefined' ? 'default' : props.text}; | |
| return<>{props.text}</>; | |
| }; |
There was a problem hiding this comment.
TypeScript is probably going to be the biggest blocker here. But codemodding that perfectly seems like a pretty huge task.
| @@ -0,0 +1,12 @@ | |||
| const Link = ({ href, children, ...props }) => { | |||
There was a problem hiding this comment.
What would happen if href or children are not named here e.g. { href, ...props} and <a href={href} {...props} />?
There was a problem hiding this comment.
For the example you provided, it only considers href and produces the following output:
constLink=({ href ="#", ...props})=>{return(<ahref={href}{...props}/>);};There was a problem hiding this comment.
@eps1lon
We reviewed this case with @mohebifar 's help, and I understood your point. What do you think about doing something similar to the solution I suggested for the previous case?
Before:
constMyComp=({foo, ...props}){console.log(props.bar)}MyComp.defaultProps={foo: "hello",bar: "bye"}After:
constMyComp=({foo ='hello', ...props}){
props ={...props,bar: typeofprops.bar==='undefined' ? 'bye' : props.bar}console.log(props.bar)}There was a problem hiding this comment.
@eps1lon
I fix it in this commit:
13e3d842e861a8f68c99a07b034dbd83a40cc96c
Hoisted default object values outside function parameters to avoid invalidating memoization when migrating from .defaultProps to function default parameters.
amirabbas-gh
commented
Feb 15, 2025
@eps1lon |
eps1lon
left a comment
There was a problem hiding this comment.
Looks good. I'd recommend running this on some actual codebases to verify. I don't think we have any more defaultProps but I can test it on our larger codebases internally as a sanity check. Can you ping me once npx codemod react/19/replace-default-props is available?
amirabbas-gh
commented
Feb 19, 2025
Final version published on Codemod registry! 🚀The final version has been published! All updates are now available on the Codemod registry. You can now run: npx codemod react/19/replace-default-propsto execute the codemod with the latest improvements. @eps1lon Let me know if you need anything! 😊 |
alexbit-codemod
commented
Feb 19, 2025
great job @amirabbas-gh and thank you @eps1lon for code review. i also tested the codemod and all lgtm. this can be merged now... cc @rickhanlonii , @mohebifar |
eps1lon
left a comment
There was a problem hiding this comment.
I can't run the tests locally.
$yarntestdefault-props●Validation Warning:
Unknownoption"extensionsToTreatAsEsm"withvalue[".ts",".tsx",".js",".jsx"]wasfound.Thisisprobablyatypingmistake.Fixingitwillremovethismessage.Configuration Documentation:
https://jestjs.io/docs/configuration.htmlts-jest[versions](WARN)Version4.8.4oftypescriptinstalledhasnotbeentestedwithts-jest.Ifyou're experiencing issues, consider using a supported version (>=2.7.0 <4.0.0). Please do not report issues in ts-jest if you are using unsupported versions.
ts-jest[config](WARN)TypeScriptdiagnostics(customizeusing`[jest-config].globals.ts-jest.diagnostics`option):
messageTS151001: Ifyouhaveissuesrelatedtoimports,youshouldconsidersetting`esModuleInterop`to`true`inyourTypeScriptconfigurationfile(usually`tsconfig.json`).Seehttps://blogs.msdn.microsoft.com/typescript/2018/01/31/announcing-typescript-2-7/#easier-ecmascript-module-interoperability for more information.FAILtransforms/__tests__/react-19-replace-default-props.codemod.test.ts●TestsuitefailedtorunCannotfind module '@codemod.com/codemod-utils'from'react-19-replace-default-props.codemod.ts'The warnings also seem concerning. Especially related to ts-jest when we just added this dependency.
amirabbas-gh
commented
Apr 1, 2025
@eps1lon There were some issues in the PR as well as in some of Codemod's packages, which I have fixed. Please pull changes, reinstall the packages, and make sure to run the tests again. |
📚 Description
This PR is created to update the react-codemod repository with the updates for the react/19/replace-default-props codemod and to align the open-source content of this codemod in react-codemod similar to the Codemod repository.
Added Codemod Utils Package
@codemod.com/codemod-utilspackage as a dependency to facilitate codemod development.Added Custom TypeScript Configuration for Codemods
react-19-replace-default-propsto handle default props migration for React 19.npx codemod react/19/replace-default-props🧪 Test Plan
The following steps were taken to ensure the changes function as intended:
react-19-replace-default-propstransform was executed against test cases.