类组件(Class components)
- 无论是使用函数或是类来声明一个组件,它决不能修改它自己的 props。
- 所有 React 组件都必须是纯函数,并禁止修改其自身 props。
- React是单项数据流,父组件改变了属性,那么子组件视图会更新。
- 属性 props是外界传递过来的,状态 state是组件本身的,状态可以在组件中任意修改
- 组件的属性和状态改变都会更新视图。
class Welcome extends React.Component {
render() {
return (
<h1>Welcome { this.props.name }</h1>
);
}
}
ReactDOM.render(<Welcome name='react' />, document.getElementById('root'));
函数组件(functional component)
函数组件接收一个单一的 props 对象并返回了一个React元素
function Welcome (props) {
return <h1>Welcome {props.name}</h1>
}
ReactDOM.render(<Welcome name='react' />, document.getElementById('root'));
区别
- 语法上
两者最明显的不同就是在语法上,函数组件是一个纯函数,它接收一个props对象返回一个react元素。而类组件需要去继承React.Component并且创建render函数返回react元素,这将会要更多的代码,虽然它们实现的效果相同。
- 状态管理
因为函数组件是一个纯函数,你不能在组件中使用setState(),这也是为什么把函数组件称作为无状态组件。
如果你需要在你的组件中使用state,你可以选择创建一个类组件或者将state提升到你的父组件中,然后通过props对象传递到子组件。
- 生命周期钩子
你不能在函数组件中使用生命周期钩子,原因和不能使用state一样,所有的生命周期钩子都来自于继承的React.Component中。
因此,如果你想使用生命周期钩子,那么需要使用类组件。
注意:在react16.8版本中添加了hooks,使得我们可以在函数组件中使用useState钩子去管理state,使用useEffect钩子去使用生命周期函数。因此,2、3两点就不是它们的区别点。从这个改版中我们可以看出作者更加看重函数组件,而且react团队曾提及到在react之后的版本将会对函数组件的性能方面进行提升。
- 调用方式
如果SayHi是一个函数,React需要调用它:
// 你的代码
function SayHi() {
return <p>Hello, React</p>
}
// React内部
const result = SayHi(props) // » <p>Hello, React</p>
如果SayHi是一个类,React需要先用new操作符将其实例化,然后调用刚才生成实例的render方法:
// 你的代码
class SayHi extends React.Component {
render() {
return <p>Hello, React</p>
}
}
// React内部
const instance = new SayHi(props) // » SayHi {}
const result = instance.render() // » <p>Hello, React</p>
可想而知,函数组件重新渲染将重新调用组件方法返回新的react元素,类组件重新渲染将new一个新的组件实例,然后调用render类方法返回react元素,这也说明为什么类组件中this是可变的。