为什么推荐使用函数式组件而不是类组件
在 React.js 中,有两种主要类型的组件:
- 函数式组件
- 类组件
函数式组件 基本上是JavaScript函数,接受props作为参数并返回要呈现的React元素。它们比类组件更简单,更简洁,更容易理解和测试。它们通常也更快速地进行渲染。
类组件 则是JavaScript类,扩展自React.Component类。相比函数式组件,它们具有更多的功能和能力,例如状态和生命周期方法。对于更复杂的组件,例如需要管理内部状态或处理用户事件的组件,它们也很有用。
通常情况下,除非你特别需要类组件提供的附加功能,否则建议使用函数式组件。随着React 16.8中引入hooks的功能,函数式组件现在也可以处理状态和生命周期方法,使它们更强大和灵活。下面是一些考虑使用函数式组件而不是类组件的原因:
- 简单性: 函数式组件比类组件更简单,更易于理解。它们没有生命周期方法、状态和this绑定增加的复杂性。
- 性能: 函数式组件比类组件更高效。它们没有为每次渲染创建新实例的额外开销。而且函数式组件可以使用React Hooks,这使得它们的性能更高。
- 更易于测试: 函数式组件比类组件更易于测试。因为它们只是普通的JavaScript函数,可以使用像Jest这样的JavaScript测试工具进行测试。
- 更易于重用: 函数式组件比类组件更易于重用。因为它们只是普通的JavaScript函数,可以在应用程序的不同部分轻松重复使用。
- 更易于理解: 函数式组件比类组件更易于理解。因为它们只是普通的JavaScript函数,它们的行为更可预测、更易于理解。
- Hooks: 函数式组件可以使用React Hooks,在函数式组件中使用状态和其他React功能,而类组件不能。可以参考这篇GFG文章以更好地理解Hooks – 链接。
创建React项目:
步骤1: 使用npx命令安装React模块以创建一个React应用程序。
npx create-react-app project name
步骤2: 创建完React项目后,通过以下命令进入文件夹执行不同的操作。
cd project name
步骤3: 在终端中打开并输入以下命令,将项目托管到本地服务器上。
npm start
项目结构:
示例 1: 创建一个名为 Component 的新文件夹来存储组件文件,然后将当前的 App.js 文件内容更改为
import './App.css';
import FunctionalComponent from
'./Component/FunctionalComponent';
function App() {
return (
<div className="App">
<FunctionalComponent name="GFG" />
</div>
);
}
export default App;
以 ES6箭头函数 或函数声明的形式定义React功能组件。下面的代码位于Component文件夹中的FunctionalComponent.js文件中。这是一个React基本功能组件的示例:
下面是使用 ES6箭头函数 的相同组件:
import React from 'react'
const FunctionalComponent = (props) => {
return (
<div>
<h1>
This is an example of
Functional Component.
</h1>
<p>
name passed from App Component to
Functional Component using props
</p>
<h2>{props.name}</h2>
</div>
)
}
export default FunctionalComponent;
上面的两个代码将有相同的输出:
将任何类组件转换为函数组件的步骤:
- 引入所有必要的库。
- 将 class 声明替换为 function 声明。
- 在函数组件中不再使用 this ,因此从代码中删除 this 。例如(将 this.props 替换为简单的 props )。
- 像普通函数一样将所有props传递进去。
- 使用 useState() 钩子替换 this.state 。
- 使用 useEffect() 钩子替换所有生命周期方法,如 ComponentDidMount() 。
- 最后,移除 render() 方法,直接从函数中返回组件的JSX。
示例2: 下面是 App.js 文件的代码,对于类组件和函数组件来说是相同的。
// Below is the code for App.js file and
// it will remain same for both class
// component and functional component.
import './App.css';
import MyComponent from './Component/MyComponent';
function App() {
return (
<div className="App">
<MyComponent name="GFG-Counter" />
</div>
);
}
export default App;
- 在 类组件 中的代码
// Class component
import React, { Component } from 'react';
class MyComponent extends Component {
constructor(props) {
super(props);
this.state = {
count: 0,
};
}
componentDidMount() {
console.log('Component mounted');
}
handleClick = () => {
this.setState({ count: this.state.count + 1 });
};
render() {
return (
<div>
<h1>{this.props.name}</h1>
<p>Count: {this.state.count}</p>
<button onClick={this.handleClick}>
Click me
</button>
</div>
);
}
}
export default MyComponent;
- 应用上述规则到类组件代码后,将以下代码添加到 Component/MyComponent.js 。
// Functional component
import React, { useState, useEffect } from 'react';
function MyComponent(props) {
const [count, setCount] = useState(0);
useEffect(() => {
console.log('Component mounted');
}, []);
const handleClick = () => {
setCount(count + 1);
};
return (
<div>
<h1>{props.name}</h1>
<p>Count: {count}</p>
<button onClick={handleClick}>Click me</button>
</div>
);
}
export default MyComponent;
这只是一个基本示例,根据原始类组件的复杂性,转换为功能组件时可能需要进行其他更改。
注意: 需要注意的是,在React中仍然可以使用类组件,并且可以在必须使用生命周期方法或本地状态的特定情况下使用。然而,在大多数情况下,建议使用具有Hooks的功能组件代替。