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

时间:2016-07-07 16:15:11

标签: javascript reactjs ecmascript-6

我是ES6的新手。 在编写React组件的不同方法上有点困惑。 我开始使用" React.createClass"然后转移到"扩展React.Component"使用ES6类语法。

现在关注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

我怎样才能重构这个&#34;功能&#34;转移到扩展React.component的ES6类?我想返回JSX是render()方法,不是吗? 那么onClick,已完成,文本参数呢?

谢谢

3 个答案:

答案 0 :(得分:4)

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

如果您使用babel来转换代码并且拥有class properties transform,那么您可以执行以下操作:

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

为了清楚这第二个例子不能被认为是“标准ES6”,但是我发现静态属性更加清晰,所以我认为值得展示这种方法。

答案 1 :(得分:4)

对于你的组件实际上最好是使它成为一个纯函数,而不是ES6类,因为它可以呈现为它的props函数并且不维护状态。您仍然可以使用ES6语法(导出,箭头功能等)。

Facebook's explanation:&#34;在理想的世界中,大多数组件都是无状态函数,因为将来我们还可以通过避免不必要的检查和内存来对这些组件进行性能优化。分配。如果可能,这是推荐的模式。&#34;

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

答案 2 :(得分:0)

从 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;

如果您不想要隐式孩子,您可以删除 import type 行并重写如下:

const Todo = ({ onClick, hasCompleted, text }: TodoProps) => (

但是,如果您这样做了,您还需要将 children 添加到类型声明中,并花时间试图弄清楚它应该如何输入——如果使用 FC 作为 {{假设为 1}}。

有关在 TypeScript 中声明函数的更多信息,请访问 TypeScript 文档中的 More on Functions