I'm new to ES6. Got a bit confused on different ways to write a React ponent. I started with a "React.createClass" then moved to "extends React.Component" with ES6 classes syntax.
Following Redux tutorial now I see they define ponents in this way
import React, { PropTypes } from 'react'
const Todo = ({ onClick, pleted, text }) => (
<li onClick={onClick} style={{ textDecoration: pleted ? 'line-through' : 'none' }} >
{text}
</li>
)
Todo.propTypes = {
onClick: PropTypes.func.isRequired,
pleted: PropTypes.bool.isRequired,
text: PropTypes.string.isRequired
}
export default Todo
How can I refactor this "function" moving to a ES6 class which extends Reactponent? I guess the return JSX is the render() method, isn't it? What about onClick, pleted, text arguments?
Thank you
I'm new to ES6. Got a bit confused on different ways to write a React ponent. I started with a "React.createClass" then moved to "extends React.Component" with ES6 classes syntax.
Following Redux tutorial now I see they define ponents in this way
import React, { PropTypes } from 'react'
const Todo = ({ onClick, pleted, text }) => (
<li onClick={onClick} style={{ textDecoration: pleted ? 'line-through' : 'none' }} >
{text}
</li>
)
Todo.propTypes = {
onClick: PropTypes.func.isRequired,
pleted: PropTypes.bool.isRequired,
text: PropTypes.string.isRequired
}
export default Todo
How can I refactor this "function" moving to a ES6 class which extends React.ponent? I guess the return JSX is the render() method, isn't it? What about onClick, pleted, text arguments?
Thank you
Share Improve this question asked Jul 7, 2016 at 16:15 MarcoMarco 7893 gold badges9 silver badges23 bronze badges3 Answers
Reset to default 4For your ponent 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 ponents would be stateless functions because in the future we’ll also be able to make performance optimizations specific to these ponents by avoiding unnecessary checks and memory allocations. This is the remended pattern, when possible."
import { PropTypes } from 'react'
function Todo = (props) => (
<li onClick={props.onClick} style={{ textDecoration: props.pleted ? 'line-through' : 'none' }} >
{props.text}
</li>
)
Todo.propTypes = {
onClick: PropTypes.func.isRequired,
pleted: PropTypes.bool.isRequired,
text: PropTypes.string.isRequired
}
export default Todo
The ES6 syntax equivalent would be:
import React, { Component, PropTypes } from 'react'
class Todo extends Component {
render() {
const { onClick, pleted, text } = this.props
return (
<li onClick={onClick} style={{ textDecoration: pleted ? 'line-through' : 'none' }} >
{text}
</li>
)
}
}
Todo.propTypes = {
onClick: PropTypes.func.isRequired,
pleted: 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,
pleted: PropTypes.bool.isRequired,
text: PropTypes.string.isRequired
}
render() {
const { onClick, pleted, text } = this.props
return (
<li onClick={onClick} style={{ textDecoration: pleted ? '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.
Moving beyond ES6 into TypeScript, for React version 17 and above you can do:
import type { FC } from "react";
interface TodoProps {
onClick: () => void;
hasCompleted: () => boolean;
text: string;
}
const Todo: FC<TodoProps> = ({ onClick, hasCompleted, text }) => (
<li
onClick={onClick}
style={{ textDecoration: hasCompleted ? "line-through" : "none" }}
>
{text}
</li>
);
export default Todo;
If you don't want implicit children you can drop the import type
line and rewrite like:
const Todo = ({ onClick, hasCompleted, text }: TodoProps) => (
If you do, however, you'll also need to add children
to the type declaration and spend time trying to figure out how it should be typed—not necessary if using FC
as children
are assumed.
For more info on declaring Functions in TypeScript visit More on Functions in the TypeScript docs.