将 React 组件从函数重构为 ES6 类
Posted
技术标签:
【中文标题】将 React 组件从函数重构为 ES6 类【英文标题】:Refactor a React component from function to ES6 class 【发布时间】:2016-11-10 01:39:38 【问题描述】:我是 ES6 新手。 对编写 React 组件的不同方式感到有些困惑。 我从“React.createClass”开始,然后移至使用 ES6 类语法“扩展 React.Component”。
按照 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
我怎样才能重构这个“函数”移动到一个扩展 React.component 的 ES6 类?我猜返回 JSX 是 render() 方法,不是吗? onClick、completed、文本参数呢?
谢谢
【问题讨论】:
【参考方案1】:对于你的组件,实际上最好将其设为纯函数,而不是 ES6 类,因为它可以作为其props
的函数进行渲染,并且不维护状态。不过,您仍然可以使用 ES6 语法(导出、箭头函数等)。
Facebook's explanation:“在理想情况下,您的大多数组件将是无状态函数,因为将来我们还可以通过避免不必要的检查和内存分配来针对这些组件进行性能优化。这是推荐的模式,如果可能的话。”
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
【讨论】:
这正是应该做的。仅仅因为您可以将组件编写为 ES6 类并不意味着所有组件都应该是类。 我支持您的解决方案。我不知道你可以不必为组件中的道具使用 PropTypes.shape。 避免回答问题:“做 X 的最好方法就像 ABC,因此这里是 ABC” - 他想要纯函数版本的 ES6 版本,而不是重复他的确切问题参考。 不应该是const Todo = ...
(或function Todo(props) ...
)而不是function Todo = ...
吗?【参考方案2】:
等效的 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”,但是我发现静态属性非常干净,所以我认为也值得展示这种方法。
【讨论】:
OP 要求一个 ES6 类,你的回答是语法错误。【参考方案3】:从 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;
如果您不想要 implicit 孩子,您可以删除 import type
行并重写如下:
const Todo = ( onClick, hasCompleted, text : TodoProps) => (
但是,如果您这样做了,您还需要将children
添加到类型声明中,并花时间尝试找出应该如何输入它——如果假设使用FC
,则不需要使用children
。
有关在 TypeScript 中声明函数的更多信息,请访问 TypeScript 文档中的More on Functions。
【讨论】:
以上是关于将 React 组件从函数重构为 ES6 类的主要内容,如果未能解决你的问题,请参考以下文章