浅析React有状态组件和无状态组件
在适合的情况下,我们都应该且必须使用无状态组件。无状态组件不像其他两种方法在调用时会创建新实例,它创建时始终保持了一个实例,避免了不必要的检查和内存分配,做到了内部优化。——摘自《深入 React 技术栈》
无状态组件
无状态组件又称变现性组件或者木偶组件,为何叫木偶组件?因为它只关心数据传递props
,只能访问输入的 props
,同样的 props
会得到同样的渲染结果,不会有副作用。
无状态组件无法访问生命周期的方法,因为它是不需要组件生命周期管理和状态管理,所以底层实现这种形式的组件时是不会实现组件的生命周期方法。所以无状态组件是不能参与组件的各个生命周期管理的。
无状态组件不会被实例化,无实例化过程也就不需要分配多余的内存,所以相比有状态组件,它的性能更优。同样,由于没有实例化,所以无法访问组件this
中的对象,例如:this.ref
、this.state
等均不能访问。若想访问就不能使用这种形式来创建组件。
它有两种情况,要么是纯粹的渲染 html
内容,不需要对数据进行判断和处理。要么这个组件所需要的数据,都是来自于父组件props
传递来或者 Redux
的 store
中的数据),无状态组件应该保持模板的纯粹性。
const Title = (props) => (
<div className="title-style">
{props.word}
</div>
)
export default Title;
有状态组件
有状态组件又被称为容器组件或者聪明组件,它主要用来处理数据或者页面逻辑交互。它比无状态功能更加强大。类组件可以维护自身的状态变量,即组件的state
。
有状态组件组件还有不同的生命周期方法,可以让开发者能够在组件的不同阶段(挂载、更新、卸载),对组件做更多的控制。
在React
组件中有状态组件相当于一个枢纽站。因为它就像一个容器,里面包含的是无状态组件,在容器组件中获取完数据后,再将这些数据分配给子组件。就像下面的例子,Title
是一个无状态组件,数据在有状态组件中处理完在传递给给Title
,
import Title from './Title.js';
class Title extends React.Component{
constructor(props){
super(props);
this.state={
titleWord:'hello world'
}
}
render(){
return(
<div className="title-style">
<Title word={this.state.titleWord}/>
</div>
)
}
}
export default Title;
从性能角度分析两者区别
这里摘抄自如何为组件增加状态?
通常,函数(function
)与类(class
)最大的区别是:是否能够维护自己的数据(即状态)。函数基本上仅关注动作(action
),而不关心数据的维护,不用维持一个状态,不用把自己的数据保存在内存中。函数使用的数据是从外部获取(或者不获取数据),函数运行时,会完成一系列的动作,最后将结果返回(也可能不返回,仅仅是完成指定的动作)。相对而言,类有能力维护状态(保存数据),也可以定义自己的一系列动作。
一般来说,函数的速度较快,适合用于做表现层,而类能够处理复杂逻辑和状态,适合做逻辑层和数据层。所以,对于 React
来说,一般选择函数来无状态组件,得到所谓的无状态函数(stateless function
),好处是渲染的速度快,所以多使用无状态组件,尽量不要让数据散落在各个组件中。数据集中管理可以更好的保持数据的一致性和可维护性。
有状态组件就是使用类来生成。类可以有自己的状态,维护自己的数据,也是完全符合有状态组件的要求。但是类相对来说速度比函数慢,影响渲染的性能,同时数据过于分散会给后期的维护带来比较大的困难(这也是为什么状态过多时要使用 Redux
的原因),因此要尽量控制有状态组件的数量。当然,类也可以生成无状态组件,但是既然不需要维护状态的工作,用函数能完成得更好,其实也就没有必要使用类来做无状态组件。