为啥使用无状态功能组件而不是基于类的组件?

Posted

技术标签:

【中文标题】为啥使用无状态功能组件而不是基于类的组件?【英文标题】:Why use stateless functional Components instead of class-based Components?为什么使用无状态功能组件而不是基于类的组件? 【发布时间】:2019-09-23 22:22:32 【问题描述】:

我正在学习 ReactJS,我了解到有 UI 组件和容器组件。容器组件是使用classes 扩展React.Component 实现的,并包含state 和旧的render 方法,而UI 组件是使用functions 创建的,它们只关心UI,因为它们只从props.

无状态功能组件示例:

const Ninjas = (props) => 
    const  ninjas  = props;

    const ninjalist = ninjas.map((x) => 
        var divStyle = 
            color: getRandomColor(),
        ;

        return (
            <div className="ninja" key=x.key style=divStyle>
                <p>Name: x.name</p>
                <p>Age: x.age</p>
                <p>Belt: x.belt</p>
            </div>
        );
    );
    return <div className="ninja-list">ninjalist</div>;
;

export default Ninjas;

与容器组件相同的示例

export default class Ninjas extends Component 
    getRandomColor = () => 
        ....
        return color;
    ;

    render() 
        const  ninjas  = this.props;

        const ninjalist = ninjas.map((x) => 
            var divStyle = 
                color: this.getRandomColor(),
            ;

            return (
                <div className="ninja" key=x.key style=divStyle>
                    <p>Name: x.name</p>
                    <p>Age: x.age</p>
                    <p>Belt: x.belt</p>
                </div>
            );
        );
        return <div className="ninja-list">ninjalist</div>;
    

所以我的问题是,当我们可以轻松完成与容器组件相同的事情时,为什么还要费心制作 UI 组件(不使用容器组件中使用的 render 方法)。

【问题讨论】:

我认为您正在尝试比较无状态功能组件与基于类的组件,“容器组件”是一个重载术语。参见例如***.com/q/36097965/3001761 是的@jonrsharpe,这正是我想要做的。你还可以回答我的问题吗?谢谢! 一种 React 模式是将功能与表示分离,这意味着您使用管理状态的容器组件和简单呈现状态的 UI 组件。每个组件过去都是基于类的,而 UI 组件只是新功能组件的完美用例。 【参考方案1】:

功能性无状态组件(您错误地称为 UI 组件,所有组件都是有状态和无状态的 UI 组件)只是创建组件的一种简单方法不需要保持内部状态。

当然,人们总是可以使用扩展React.Component 的基于类的组件。但是,如果可以的话,为什么不使用快捷方式来节省时间和空间并简化事情。没有什么强迫您创建函数式组件,您始终可以使用基于类的组件,除非您需要简化并节省时间和空间。

据Functional vs Class-Components in React文章:

那我为什么要使用函数式组件呢?

您可能会问自己,为什么要在 所有,如果他们删除了这么多好的功能。但也有一些好处 你可以通过在 React 中使用函数式组件来获得:

    函数式组件更易于阅读和测试,因为它们是没有状态或生命周期挂钩的纯 javascript 函数 您最终得到的代码更少 它们帮助您使用最佳实践。分离容器和展示组件会变得更容易,因为您需要考虑更多 如果您无权访问 setState() 你的组件 React 团队提到,在未来的 React 版本中,功能组件的性能可能会有所提升

我要添加 第 5 点,即提供直接访问 DOM 节点的功能的 React references(使用 React 16.3+)不能与功能组件一起使用。

在 React v.16.8+ 中引入了useState hooks,它使功能组件能够在保持功能的同时保持全状态。

此外,随着React.memo higher-order component 的引入,我们可以使用记忆化来避免重新渲染功能组件,因为它会为相同的道具渲染相同的东西(浅度测试差异)

【讨论】:

谢谢。那清除它。我明白为什么我需要他们两个。尽管在性能方面有区别吗? The React team mentioned that there may be a performance boost for functional component in future React versions 但现在真的有吗? 功能组件存在性能问题(例如,从纯 javascript 的角度来看,不需要扩展另一个类,没有方法等。)纯功能组件的 React boost 是下一个合乎逻辑的事情,因为不必进行生命周期挂钩或状态管理。不确定有什么优势,因为它们取决于 React 团队本身

以上是关于为啥使用无状态功能组件而不是基于类的组件?的主要内容,如果未能解决你的问题,请参考以下文章

事件处理:基于功能的组件与基于类的组件

使用反应挂钩将基于类的组件转换为功能组件[重复]

为啥我不能更新函数组件中的状态(使用钩子)?

有状态和功能性无状态组件

当组件是无状态功能时,通过显示名称查找组件,使用 Enzyme

如何在 TypeScript 中使用带有 React 无状态功能组件的子组件?