This extension for Visual Studio Code provides a quick way to refactor your React code. It allows you to extract a valid piece of component code into a new function, automatically passing the props and building the extracted component interface, if using Typescript.
Installation
Get it at Visual Studio Code Marketplace: React Extract
Features
Code Extraction: Select a valid piece of React component code that you want to refactor.
Quick Refactor Action: Use the Code Actions feature (Ctrl + .
or Cmd + .
, by default) to initiate the refactoring process.
Component Naming: Pass the component name at the input prompt.
Automatic Prop Passing: The extension will automatically identify and pass the necessary props to the new function.
TypeScript Support: If you're using TypeScript, the extension will also build the interface for the new function.
Code Placement: The new function will be placed at the bottom of the current file.
Configurations
You may customize the way that the extracted component is built, with the following options on your Settings (Ctrl + ,
or Cmd + ,
, by default):
// interface
interface ComponentProps {
// ...
}
// type
type ComponentProps = {
// ...
};
// inline
function Component(props: { onClick: () => void; value: number; options: number[] }) {
// ...
}
// arrow
const Component = () => (
//...
)
// function
function Component() {
//...
}
// true
const Component: React.FC<ComponentProps> = ({...props}) => (
//...
)
// false
const Component = ({...props}: ComponentProps) => (
//...
)
Description: Whether to do object destructure in the extracted component props parameter or not. If set to "false", the parameter will be named "props".
Accepts: "true" | "false"
Default: "true"
// true
function Component({ onClick, className }: ComponentProps) {
return <ChildComponent onClick={onClick} className={className} />;
}
// false
function Component(props: ComponentProps) {
return <ChildComponent onClick={props.onClick} className={props.className} />;
}
Note: If Destructure Props is set to false, but one of the props is a spread, props will be passed as destructured. Example:
// Before extraction
function Parent() {
const childProps = {
className: 'myClass',
onClick: () => console.log('Clicked!')
};
return <div {...childProps}>Child Component</div>;
}
// After extraction
function Parent() {
const childProps = {
className: 'myClass',
onClick: () => console.log('Clicked!')
};
return <Child {...childProps} />;
}
function Child({ ...childProps }) {
return <div {...childProps}>Child Component</div>;
}
// true
const Component: React.FC<ComponentProps> = ({ ...props }) => {
return <Extracted />;
};
// false
const Component = ({ ...props }: ComponentProps) => <Extracted />;
Contributions
If you encounter any problems or have suggestions for improvements, please open an issue. Your feedback and contribution is appreciated. If you have the agreed solution as well, please open a pull request.
Application Setup
Clone the repo, install dependencies and enter VS Code.
$ https://github.com/joao-mbn/react-extract.git
$ cd react-extract
$ npm i
$ code .
Running and Debugging the Application
- Comment the following block of code in
webpack.config.js
to avoid conflicts with the ts-lib files in the node_modules
:
plugins: [
new CopyPlugin({
patterns: [{ from: 'node_modules/typescript/lib/*.d.ts', to: '[name][ext]' }]
})
];
Running Tests
- Install the Extension Test Runner and TypeScript + Webpack Problem Matchers extensions.
- Open the Command Palette
Ctrl + Shift + P
or Cmd + Shift + P
.
- Select Task: Run Task.
- Select tasks: watch tests.
- Run the tests from the test explorer.
You can add a new folder under the src/test/components
folder with the .jsx and .tsx files and their results using the project's naming convention via a script, as follows:
$ npm run create-test myNewTestCase
Replace myNewTestCase with the appropriate test case name.
Release Notes
Checkout the Changelog
Limitations
This extension is currently not fully supportive of Class Components. You can use it just fine on them, but the passed props may be wrongy extracted. Let it be known if you wish full support on them.
Even with this disclaimer, be welcome to open issues related to its use with Class Components, as to improve the implementation when support is given.