简体   繁体   English

将 React 组件从函数重构为 ES6 类

[英]Refactor a React component from function to ES6 class

I'm new to ES6.我是 ES6 的新手。 Got a bit confused on different ways to write a React component.对编写 React 组件的不同方法有点困惑。 I started with a "React.createClass" then moved to "extends React.Component" with ES6 classes syntax.我从“React.createClass”开始,然后用 ES6 类语法转移到“扩展 React.Component”。

Following Redux tutorial now I see they define components in this way现在按照 Redux 教程,我看到他们以这种方式定义组件

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?我怎样才能重构这个“函数”移动到扩展 React.component 的 ES6 类? I guess the return JSX is the render() method, isn't it?我想返回的 JSX 是 render() 方法,不是吗? What about onClick, completed, text arguments? onClick,已完成,文本参数怎么样?

Thank you谢谢

The ES6 syntax equivalent would be:等效的 ES6 语法是:

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:如果您使用babel来转译您的代码并且您拥有类属性转换,那么您可以执行以下操作:

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.需要明确的是,第二个示例不能被视为“标准 ES6”,但是我发现静态属性非常清晰,因此我认为也值得展示这种方法。

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.因为你的组件实际上最好让它成为一个纯函数,而不是一个 ES6 类,因为它可以作为它的props的函数进行渲染并且不维护状态。 You can still use ES6 syntax though (exporting, arrow functions, etc.).您仍然可以使用 ES6 语法(导出、箭头函数等)。

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." Facebook 的解释是:“在理想的世界中,您的大部分组件将是无状态函数,因为将来我们还可以通过避免不必要的检查和内存分配来针对这些组件进行性能优化。这是推荐的模式,当可能。”

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

Moving beyond ES6 into TypeScript, for React version 17 and above you can do:从 ES6 迁移到 TypeScript,对于 React 17 及更高版本,您可以执行以下操作:

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:如果您不想要隐式孩子,您可以删除import type行并重写如下:

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.但是,如果您这样做了,您还需要将children项添加到类型声明中,并花时间试图弄清楚它应该如何键入——如果假设使用FC作为children则不需要。

For more info on declaring Functions in TypeScript visit More on Functions in the TypeScript docs.有关在 TypeScript 中声明函数的更多信息,请访问 TypeScript 文档中 关于函数的更多信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM