Codemods for everyday work with React. All support Flow, TypeScript, and plain JS.
Most of these codemods (except for convertSimpleClassComponentsToFunctions
) are intended to be called from IDE extensions, calling them
from the jscodeshift
CLI wouldn't be worth the effort.
wrapWithJSXElement
wrapWithChildFunctionElement
addProp
renderConditionally
wrapWithTernaryConditional
convertSimpleClassComponentsToFunctions
A codemod that wraps selected JSX elements inside a parent JSX element. This is intended to be called from IDE extensions, it's too cumbersome to call from the JSCodeshift CLI.
The start of the selection in the source code. This is used for determining which JSX elements to wrap.
The end of the selection in the source code. This is used for determining which JSX elements to wrap.
The name of the JSX element to wrap with.
const Foo = () => (
<div>
{foo}
{bar}
<span />
{baz}
</div>
)
jscodeshift -t path/to/react-codemorphs/wrapWithJSXElement.js \
--selectionStart=<before {foo}> \
--selectionEnd=<before {baz}> \
--name=Test
Foo.ts
const Foo = () => (
<div>
<Test>
{foo}
{bar}
<span />
</Test>
{baz}
</div>
)
A codemod that wraps a selected JSX element inside a parent JSX element with a child function.
The start of the selection in the source code. This is used for determining which JSX element to wrap.
The end of the selection in the source code. This is used for determining which JSX element to wrap.
The name of the JSX element to wrap with.
const Foo = () => (
<div>
<Bar />
</div>
)
jscodeshift -t path/to/react-codemorphs/wrapWithChildFunctionElement.js \
--selectionStart=<in the middle of Bar> \
--selectionEnd=<in the middle of Bar> \
--name=Test
Foo.ts
const Foo = () => (
<div>
<Test>{(): React.ReactNode => <Bar />}</Test>
</div>
)
A codemod that adds the identifier under the cursor as a prop to the surrounding component.
Adds a prop type declaration if possible, and binds the identifier via destructuring on props
or replaces it with a reference to props
/this.props
.
The start of the selection in the source code. This is used for determining which property to add.
The end of the selection in the source code. This is used for determining which property to add.
The Flow or TypeScript type annotation to use for the property type declaration.
Cursor is positioned in the middle of text
below:
import * as React from 'react'
interface Props {}
const Foo = (props: Props) => <div>{text}</div>
jscodeshift -t path/to/react-codemorphs/addProp.js \
--selectionStart=<in the middle of text> \
--selectionEnd=<in the middle of text> \
--typeAnnotation=string
Foo.ts
import * as React from 'react'
interface Props {
text: string
}
const Foo = (props: Props) => <div>{props.text}</div>
Wraps the selected JSX in {true && ...}
. If
there are multiple siblings selected, wraps in {true && <React.Fragment>...</React.Fragment>}
.
If you want to wrap in a ternary conditional like Glean's
"Render Conditionally" refactor, see wrapWithTernaryConditional
.
The start of the selection in the source code. This is used for determining which JSX elements to wrap.
The end of the selection in the source code. This is used for determining which JSX elements to wrap.
const Foo = () => (
<div>
{foo} bar
<span />
{baz}
</div>
)
jscodeshift -t path/to/react-codemorphs/renderConditionally.js \
--selectionStart=<before {foo}> \
--selectionEnd=<before {baz}> \
Foo.ts
const Foo = () => (
<div>
{true && (
<React.Fragment>
{foo} bar
<span />
</React.Fragment>
)}
{baz}
</div>
)
Wraps the selected JSX in {true ? ... : null}
. If
there are multiple siblings selected, wraps in {true ? <React.Fragment>...</React.Fragment> : null}
.
The start of the selection in the source code. This is used for determining which JSX elements to wrap.
The end of the selection in the source code. This is used for determining which JSX elements to wrap.
const Foo = () => (
<div>
{foo} bar
<span />
{baz}
</div>
)
jscodeshift -t path/to/react-codemorphs/wrapWithTernaryConditional.js \
--selectionStart=<before {foo}> \
--selectionEnd=<before {baz}> \
Foo.ts
const Foo = () => (
<div>
{true ? (
<React.Fragment>
{foo} bar
<span />
</React.Fragment>
) : null}
{baz}
</div>
)
Converts React.Component
subclasses with only a render
method (no lifecycle methods, constructors, or class properties other than propTypes
, contextTypes
, defaultProps
, and no state
type parameter) into functional components.
import * as React from 'react'
import PropTypes from 'prop-types'
export default class Foo extends React.Component<Props> {
static propTypes = {
title: PropTypes.string.isRequired,
}
render(): React.ReactNode | null {
return <div>{this.props.title}</div>
}
}
jscodeshift -t path/to/react-codemorphs/convertSimpleClassComponentsToFunctions.js <file>
import * as React from 'react'
import PropTypes from 'prop-types'
export default function Foo(props: Props): React.ReactNode | null {
return <div>{props.title}</div>
}
Foo.propTypes = {
title: PropTypes.string.isRequired,
}