Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Refactor a React component from function to ES6 class

I'm new to ES6. Got a bit confused on different ways to write a React component. I started with a "React.createClass" then moved to "extends React.Component" with ES6 classes syntax.

Following Redux tutorial now I see they define components in this way

import React, { PropTypes } from 'react'

const Todo = ({ onClick, completed, text }) => (
    <li onClick={onClick} style={{ textDecoration: completed ? 'line-through' : 'none' }} >
        {text}
    </li>
)

Todo.propTypes = {
    onClick: PropTypes.func.isRequired,
    completed: PropTypes.bool.isRequired,
    text: PropTypes.string.isRequired
}

export default Todo

How can I refactor this "function" moving to a ES6 class which extends React.component? I guess the return JSX is the render() method, isn't it? What about onClick, completed, text arguments?

Thank you

like image 679
Marco Avatar asked Jul 07 '16 16:07

Marco


2 Answers

For your component is actually best to make it a pure function, rather than an ES6 class, because it can render as a function of its props and does not maintain state. You can still use ES6 syntax though (exporting, arrow functions, etc.).

Facebook's explanation: "In an ideal world, most of your components would be stateless functions because in the future we’ll also be able to make performance optimizations specific to these components by avoiding unnecessary checks and memory allocations. This is the recommended pattern, when possible."

import { PropTypes } from 'react'

function Todo = (props) => (
    <li onClick={props.onClick} style={{ textDecoration: props.completed ? 'line-through' : 'none' }} >
        {props.text}
    </li>
)

Todo.propTypes = {
    onClick: PropTypes.func.isRequired,
    completed: PropTypes.bool.isRequired,
    text: PropTypes.string.isRequired
}

export default Todo
like image 173
ebuat3989 Avatar answered Oct 05 '22 09:10

ebuat3989


The ES6 syntax equivalent would be:

import React, { Component, PropTypes } from 'react'

class Todo extends Component {
  render() {
    const { onClick, completed, text } = this.props

    return (
      <li onClick={onClick} style={{ textDecoration: completed ? 'line-through' : 'none' }} >
          {text}
      </li>
    )
  }
}
Todo.propTypes = {
  onClick: PropTypes.func.isRequired,
  completed: PropTypes.bool.isRequired,
  text: PropTypes.string.isRequired
}

export default Todo

If you are using babel to transpile your code and you have the class properties transform then you can do the following:

import React, { Component, PropTypes } from 'react'

class Todo extends Component {
  static propTypes = {
    onClick: PropTypes.func.isRequired,
    completed: PropTypes.bool.isRequired,
    text: PropTypes.string.isRequired
  }

  render() {
    const { onClick, completed, text } = this.props

    return (
      <li onClick={onClick} style={{ textDecoration: completed ? 'line-through' : 'none' }} >
          {text}
      </li>
    )
  }
}

export default Todo

Just to be clear this second example cannot be considered "standard ES6", however I find the static properties so much cleaner so I thought it was worth showing this approach too.

like image 38
ctrlplusb Avatar answered Oct 05 '22 09:10

ctrlplusb