wix-incubator / vscode-glean

The extension provides refactoring tools for your React codebase
MIT License
1.46k stars 56 forks source link

Convert a stateful component to a stateless one #6

Closed itaibenda closed 5 years ago

Jefoss commented 6 years ago

implemented basic functionality in b375bcd

kevinbarabash commented 5 years ago

I'm trying to convert the following stateful component to a stateless one but all I get in the menu "Convert to Stateful".

// @flow
import * as React from "react";

type LinkProps = {|
    // Where do I go?
    children: React.Node,
    // Link me up, scotty!
    href: string,
|};

export class Link extends React.Component<LinkProps> {
    render() {
        return (
            <a
                className={css(styles.link)}
                href={this.props.href}
                target="_blank"
            >
                {this.props.children}
            </a>
        );
    }
}
borislit commented 5 years ago

@kevinbarabash thanks for the issue! Ill have a look ASAP

zachhardesty7 commented 5 years ago

Tried to convert a stateful class (see below) with useless state to a functional component. The exact error output can be seen below the component. If this isn't the right place to post this log, feel free to move it! I'd be willing to help work on it if I'm given some pointers as I'm a relative beginner.

import React from 'react'
import PropTypes from 'prop-types'
import { Link } from 'react-scroll'
import GImage from 'gatsby-image'
import {
  Container,
  Input,
  Menu
} from 'semantic-ui-react'

import { calcDuration } from '../utils'

import './Navigation.scss'

export default class Navigation extends React.Component {
  state = { activeItem: 'home' }

  handleItemClick = (e, { name }) => this.setState({ activeItem: name })

  render() {
    // eslint-disable-next-line no-unused-vars
    const { activeItem } = this.state // REVIEW: stick header?
    const {
      pages,
      logo,
      logoAlt,
      size,
      search,
      centered
    } = this.props

    return (
      <Container textAlign={centered && 'center'}>
        <Menu id='nav' size={size} compact text secondary>
          {logo && (
            <Menu.Item
              as={Link}
              to=''
              key='logo'
              spy
              smooth
              duration={calcDuration}
              tabIndex='0'
              name=''
            >
              <GImage fixed={logo} alt={logoAlt} className='logo' />
            </Menu.Item>
          )}

          {pages.map(page => (
            <Menu.Item
              as={Link}
              to={`${page.toLowerCase().replace(' ', '-')}`}
              key={`${page.toLowerCase().replace(' ', '-')}`}
              spy
              smooth
              duration={calcDuration}
              tabIndex='0'
              name={page}
            />
          ))}

          {search && (
            <Menu.Menu position='right'>
              <Menu.Item>
                <Input icon='search' placeholder='Search Properties...' />
              </Menu.Item>
            </Menu.Menu>
          )}
        </Menu>
      </Container>
    )
  }
}

Navigation.propTypes = {
  logo: PropTypes.oneOfType([
    PropTypes.element, PropTypes.object
  ]),
  logoAlt: PropTypes.string,
  size: PropTypes.string,
  search: PropTypes.bool,
  centered: PropTypes.bool,
  pages: PropTypes.arrayOf(PropTypes.string)
}

Navigation.defaultProps = {
  logo: {},
  logoAlt: '',
  size: 'large',
  search: false,
  centered: false,
  pages: []
}
[2018-10-25 15:49:52.802] [renderer4] [error] Cannot read property 'selection' of undefined: TypeError: Cannot read property 'selection' of undefined
    at Object.selectedText ({current-user}\.vscode-insiders\extensions\wix.glean-4.0.3\out\editor.js:37:30)
    at CompleteActionProvider.provideCodeActions ({current-user}\.vscode-insiders\extensions\wix.glean-4.0.3\out\extension.js:14:31)
    at {current-user}\AppData\Local\Programs\Microsoft VS Code Insiders\resources\app\out\vs\workbench\node\extensionHostProcess.js:508:787
    at {current-user}\AppData\Local\Programs\Microsoft VS Code Insiders\resources\app\out\vs\workbench\node\extensionHostProcess.js:113:941
    at new Promise (<anonymous>)
    at Object.t.asThenable ({current-user}\AppData\Local\Programs\Microsoft VS Code Insiders\resources\app\out\vs\workbench\node\extensionHostProcess.js:113:909)
    at e.provideCodeActions ({current-user}\AppData\Local\Programs\Microsoft VS Code Insiders\resources\app\out\vs\workbench\node\extensionHostProcess.js:508:746)
    at {current-user}\AppData\Local\Programs\Microsoft VS Code Insiders\resources\app\out\vs\workbench\node\extensionHostProcess.js:523:308
    at e._withAdapter ({current-user}\AppData\Local\Programs\Microsoft VS Code Insiders\resources\app\out\vs\workbench\node\extensionHostProcess.js:519:234)
    at e.$provideCodeActions ({current-user}\AppData\Local\Programs\Microsoft VS Code Insiders\resources\app\out\vs\workbench\node\extensionHostProcess.js:523:270)
    at t._doInvokeHandler ({current-user}\AppData\Local\Programs\Microsoft VS Code Insiders\resources\app\out\vs\workbench\node\extensionHostProcess.js:608:583)
    at t._invokeHandler ({current-user}\AppData\Local\Programs\Microsoft VS Code Insiders\resources\app\out\vs\workbench\node\extensionHostProcess.js:608:249)
    at t._receiveRequest ({current-user}\AppData\Local\Programs\Microsoft VS Code Insiders\resources\app\out\vs\workbench\node\extensionHostProcess.js:606:801)
    at t._receiveOneMessage ({current-user}\AppData\Local\Programs\Microsoft VS Code Insiders\resources\app\out\vs\workbench\node\extensionHostProcess.js:605:772)
    at {current-user}\AppData\Local\Programs\Microsoft VS Code Insiders\resources\app\out\vs\workbench\node\extensionHostProcess.js:603:611
    at {current-user}\AppData\Local\Programs\Microsoft VS Code Insiders\resources\app\out\vs\workbench\node\extensionHostProcess.js:103:817
    at e.fire ({current-user}\AppData\Local\Programs\Microsoft VS Code Insiders\resources\app\out\vs\workbench\node\extensionHostProcess.js:105:263)
    at a ({current-user}\AppData\Local\Programs\Microsoft VS Code Insiders\resources\app\out\vs\workbench\node\extensionHostProcess.js:156:333)
    at Socket._socketDataListener ({current-user}\AppData\Local\Programs\Microsoft VS Code Insiders\resources\app\out\vs\workbench\node\extensionHostProcess.js:156:554)
    at emitOne (events.js:116:13)
    at Socket.emit (events.js:211:7)
    at addChunk (_stream_readable.js:263:12)
    at readableAddChunk (_stream_readable.js:250:11)
    at Socket.Readable.push (_stream_readable.js:208:10)
    at Pipe.onread (net.js:594:20)
[2018-10-25 15:50:07.711] [renderer4] [error] Unexpected token (2:5)
  1 | /* @babel/template */;
> 2 |      >
    |     ^
  3 |               <GImage fixed={logo} alt={logoAlt} className='logo' />
  4 |             </Menu.Item>
  5 |           )}: SyntaxError: Unexpected token (2:5)
  1 | /* @babel/template */;
> 2 |      >
    |     ^
  3 |               <GImage fixed={logo} alt={logoAlt} className='logo' />
  4 |             </Menu.Item>
  5 |           )}
    at _class.raise ({current-user}\.vscode-insiders\extensions\wix.glean-4.0.3\node_modules\@babel\parser\lib\index.js:3939:15)
    at _class.unexpected ({current-user}\.vscode-insiders\extensions\wix.glean-4.0.3\node_modules\@babel\parser\lib\index.js:5248:16)
    at _class.parseExprAtom ({current-user}\.vscode-insiders\extensions\wix.glean-4.0.3\node_modules\@babel\parser\lib\index.js:6328:20)
    at _class.parseExprAtom ({current-user}\.vscode-insiders\extensions\wix.glean-4.0.3\node_modules\@babel\parser\lib\index.js:3635:52)
    at _class.parseExprSubscripts ({current-user}\.vscode-insiders\extensions\wix.glean-4.0.3\node_modules\@babel\parser\lib\index.js:5924:21)
    at _class.parseMaybeUnary ({current-user}\.vscode-insiders\extensions\wix.glean-4.0.3\node_modules\@babel\parser\lib\index.js:5903:21)
    at _class.parseMaybeUnary ({current-user}\.vscode-insiders\extensions\wix.glean-4.0.3\node_modules\@babel\parser\lib\index.js:10213:54)
    at _class.parseExprOps ({current-user}\.vscode-insiders\extensions\wix.glean-4.0.3\node_modules\@babel\parser\lib\index.js:5812:21)
    at _class.parseMaybeConditional ({current-user}\.vscode-insiders\extensions\wix.glean-4.0.3\node_modules\@babel\parser\lib\index.js:5784:21)
    at _class.parseMaybeAssign ({current-user}\.vscode-insiders\extensions\wix.glean-4.0.3\node_modules\@babel\parser\lib\index.js:5731:21)
    at _class.parseMaybeAssign ({current-user}\.vscode-insiders\extensions\wix.glean-4.0.3\node_modules\@babel\parser\lib\index.js:10169:87)
    at _class.parseExpression ({current-user}\.vscode-insiders\extensions\wix.glean-4.0.3\node_modules\@babel\parser\lib\index.js:5684:21)
    at _class.parseStatementContent ({current-user}\.vscode-insiders\extensions\wix.glean-4.0.3\node_modules\@babel\parser\lib\index.js:7259:21)
    at _class.parseStatementContent ({current-user}\.vscode-insiders\extensions\wix.glean-4.0.3\node_modules\@babel\parser\lib\index.js:9916:58)
    at _class.parseStatement ({current-user}\.vscode-insiders\extensions\wix.glean-4.0.3\node_modules\@babel\parser\lib\index.js:7145:17)
    at _class.parseBlockOrModuleBlockBody ({current-user}\.vscode-insiders\extensions\wix.glean-4.0.3\node_modules\@babel\parser\lib\index.js:7696:23)
    at _class.parseBlockBody ({current-user}\.vscode-insiders\extensions\wix.glean-4.0.3\node_modules\@babel\parser\lib\index.js:7683:10)
    at _class.parseTopLevel ({current-user}\.vscode-insiders\extensions\wix.glean-4.0.3\node_modules\@babel\parser\lib\index.js:7110:10)
    at _class.parse ({current-user}\.vscode-insiders\extensions\wix.glean-4.0.3\node_modules\@babel\parser\lib\index.js:8510:17)
    at parse ({current-user}\.vscode-insiders\extensions\wix.glean-4.0.3\node_modules\@babel\parser\lib\index.js:10465:38)
    at parseWithCodeFrame ({current-user}\.vscode-insiders\extensions\wix.glean-4.0.3\node_modules\@babel\template\lib\parse.js:145:32)
    at parseAndBuildMetadata ({current-user}\.vscode-insiders\extensions\wix.glean-4.0.3\node_modules\@babel\template\lib\parse.js:43:15)
    at arg ({current-user}\.vscode-insiders\extensions\wix.glean-4.0.3\node_modules\@babel\template\lib\string.js:21:50)
    at Function.ast ({current-user}\.vscode-insiders\extensions\wix.glean-4.0.3\node_modules\@babel\template\lib\builder.js:47:155)
    at Object.isStatelessComp ({current-user}\.vscode-insiders\extensions\wix.glean-4.0.3\out\modules\jsx.js:143:36)
    at CompleteActionProvider.provideCodeActions ({current-user}\.vscode-insiders\extensions\wix.glean-4.0.3\out\extension.js:24:19)
    at {current-user}\AppData\Local\Programs\Microsoft VS Code Insiders\resources\app\out\vs\workbench\node\extensionHostProcess.js:508:787
    at {current-user}\AppData\Local\Programs\Microsoft VS Code Insiders\resources\app\out\vs\workbench\node\extensionHostProcess.js:113:941
    at new Promise (<anonymous>)
    at Object.t.asThenable ({current-user}\AppData\Local\Programs\Microsoft VS Code Insiders\resources\app\out\vs\workbench\node\extensionHostProcess.js:113:909)
    at e.provideCodeActions ({current-user}\AppData\Local\Programs\Microsoft VS Code Insiders\resources\app\out\vs\workbench\node\extensionHostProcess.js:508:746)
    at {current-user}\AppData\Local\Programs\Microsoft VS Code Insiders\resources\app\out\vs\workbench\node\extensionHostProcess.js:523:308
    at e._withAdapter ({current-user}\AppData\Local\Programs\Microsoft VS Code Insiders\resources\app\out\vs\workbench\node\extensionHostProcess.js:519:234)
    at e.$provideCodeActions ({current-user}\AppData\Local\Programs\Microsoft VS Code Insiders\resources\app\out\vs\workbench\node\extensionHostProcess.js:523:270)
    at t._doInvokeHandler ({current-user}\AppData\Local\Programs\Microsoft VS Code Insiders\resources\app\out\vs\workbench\node\extensionHostProcess.js:608:583)
    at t._invokeHandler ({current-user}\AppData\Local\Programs\Microsoft VS Code Insiders\resources\app\out\vs\workbench\node\extensionHostProcess.js:608:249)
    at t._receiveRequest ({current-user}\AppData\Local\Programs\Microsoft VS Code Insiders\resources\app\out\vs\workbench\node\extensionHostProcess.js:606:801)
    at t._receiveOneMessage ({current-user}\AppData\Local\Programs\Microsoft VS Code Insiders\resources\app\out\vs\workbench\node\extensionHostProcess.js:605:772)
    at {current-user}\AppData\Local\Programs\Microsoft VS Code Insiders\resources\app\out\vs\workbench\node\extensionHostProcess.js:603:611
    at {current-user}\AppData\Local\Programs\Microsoft VS Code Insiders\resources\app\out\vs\workbench\node\extensionHostProcess.js:103:817
    at e.fire ({current-user}\AppData\Local\Programs\Microsoft VS Code Insiders\resources\app\out\vs\workbench\node\extensionHostProcess.js:105:263)
    at a ({current-user}\AppData\Local\Programs\Microsoft VS Code Insiders\resources\app\out\vs\workbench\node\extensionHostProcess.js:156:333)
    at Socket._socketDataListener ({current-user}\AppData\Local\Programs\Microsoft VS Code Insiders\resources\app\out\vs\workbench\node\extensionHostProcess.js:156:554)
    at emitOne (events.js:116:13)
    at Socket.emit (events.js:211:7)
    at addChunk (_stream_readable.js:263:12)
    at readableAddChunk (_stream_readable.js:250:11)
    at Socket.Readable.push (_stream_readable.js:208:10)
    at Pipe.onread (net.js:594:20)
[2018-10-25 15:50:15.732] [renderer4] [error] Error: File is directory
    at new t (file:///F:/Users/NewZach/AppData/Local/Programs/Microsoft VS Code Insiders/resources/app/out/vs/workbench/workbench.main.js:1416:254)
    at file:///F:/Users/NewZach/AppData/Local/Programs/Microsoft VS Code Insiders/resources/app/out/vs/workbench/workbench.main.js:3380:302
    at Object.g [as _notify] (file:///F:/Users/NewZach/AppData/Local/Programs/Microsoft VS Code Insiders/resources/app/out/vs/workbench/workbench.main.js:162:971)
    at Object.enter (file:///F:/Users/NewZach/AppData/Local/Programs/Microsoft VS Code Insiders/resources/app/out/vs/workbench/workbench.main.js:166:277)
    at n.Class.derive._creator._run (file:///F:/Users/NewZach/AppData/Local/Programs/Microsoft VS Code Insiders/resources/app/out/vs/workbench/workbench.main.js:168:100)
    at n.Class.derive._creator._completed (file:///F:/Users/NewZach/AppData/Local/Programs/Microsoft VS Code Insiders/resources/app/out/vs/workbench/workbench.main.js:167:559)
    at Object.g [as _notify] (file:///F:/Users/NewZach/AppData/Local/Programs/Microsoft VS Code Insiders/resources/app/out/vs/workbench/workbench.main.js:162:971)
    at Object.enter (file:///F:/Users/NewZach/AppData/Local/Programs/Microsoft VS Code Insiders/resources/app/out/vs/workbench/workbench.main.js:166:277)
    at n.Class.derive._oncancel._run (file:///F:/Users/NewZach/AppData/Local/Programs/Microsoft VS Code Insiders/resources/app/out/vs/workbench/workbench.main.js:168:100)
    at n.Class.derive._oncancel._completed (file:///F:/Users/NewZach/AppData/Local/Programs/Microsoft VS Code Insiders/resources/app/out/vs/workbench/workbench.main.js:167:559)
    at file:///F:/Users/NewZach/AppData/Local/Programs/Microsoft VS Code Insiders/resources/app/out/vs/workbench/workbench.main.js:3392:666
    at file:///F:/Users/NewZach/AppData/Local/Programs/Microsoft VS Code Insiders/resources/app/out/vs/workbench/workbench.main.js:3393:538
    at file:///F:/Users/NewZach/AppData/Local/Programs/Microsoft VS Code Insiders/resources/app/out/vs/workbench/workbench.main.js:296:530
    at Function.<anonymous> (file:///F:/Users/NewZach/AppData/Local/Programs/Microsoft VS Code Insiders/resources/app/out/vs/workbench/workbench.main.js:3393:511)
    at file:///F:/Users/NewZach/AppData/Local/Programs/Microsoft VS Code Insiders/resources/app/out/vs/workbench/workbench.main.js:296:137
    at s (file:///F:/Users/NewZach/AppData/Local/Programs/Microsoft VS Code Insiders/resources/app/out/vs/workbench/workbench.main.js:295:684)
    at file:///F:/Users/NewZach/AppData/Local/Programs/Microsoft VS Code Insiders/resources/app/out/vs/workbench/workbench.main.js:295:788
    at _combinedTickCallback (internal/process/next_tick.js:131:7)
    at process._tickCallback (internal/process/next_tick.js:180:9)
borislit commented 5 years ago

@zachhardesty7 First of all, thanks for the initiative! Im unable to reproduce your issue. I've ran the refactoring on your exact code and it worked flawlessly. Perhaps you've inaccurately selected the component code? Keep me posted

borislit commented 5 years ago

@kevinbarabash the issue should be resolved. Please validate

zachhardesty7 commented 5 years ago

@borislit In fact, I'm actually unable to use that command at all on my Windows 10 machine. Just pulled up VSCode on my Kubuntu machine and it worked exactly as expected... I can probably test some more on Windows tomorrow, but if you have any idea of what would help ya, that would be awesome.

borislit commented 5 years ago

@zachhardesty7 It'll take some time for me to test it, as i need to get a Windows machine and going away to a conference. So in a meanwhile, any additional info would be helpful :)

kevinbarabash commented 5 years ago

@borislit it still isn't working for me. I'm using version 4.0.3.

borislit commented 5 years ago

@kevinbarabash i've tested your exact code on 4.0.3 and it worked fine (see gif below). Can you please create a screen cast of what you are seeing? (you can use Kap or any other app) kevin

kevinbarabash commented 5 years ago

I was accessing it the action from the command palette instead of the lightbulb icon. It's working for me.

kevinbarabash commented 5 years ago

One thing that's a little weird though is that it change the name of the component to lowercase.

kevinbarabash commented 5 years ago

Thanks for making this plugin. It's awesome. ❤️

borislit commented 5 years ago

@kevinbarabash Just pished a fix for lower case issue. Look for it in v4.0.4 :) Thanks