类组件与函数式组件

How Are Function Components Different from Classes?

  • 函数组件和类组件的区别
  • React 如何区分这两种组件

当我们使用 React 自定义一个组件的时候,不必关心它是类组件还是函数式组件。

// 是类还是函数 —— 无所谓
<Greeting /> // <p>Hello</p>
  • 但如果 Greeting 是一个函数,React 需要调用它。
// Greeting.js
function Greeting() {
  return <p>Hello</p>;
}

// React 内部
const result = Greeting(props); // <p>Hello</p>
  • 但如果 Greeting 是一个React 需要先将其实例化,再调用刚才生成实例的 render 方法:
// Greeting.js
class Greeting extends React.Component {
  render() {
    return <p>Hello</p>;
  }
}

// React 内部
const instance = new Greeting(props); // Greeting {}
const result = instance.render(); // <p>Hello</p>

TIP

React通过以下方式来判断组件的类型:

// React 内部
class Component {}
Component.prototype.isReactComponent = {};

// 检查方式
class Greeting extends React.Component {}
console.log(Greeting.prototype.isReactComponent); // {}

引申: 为什么在 React 中的自定义组件需要大写字母开头?

我们知道在 React 中创建组件有 2 种方式,一种是 jsx 另外一种是React.createElement。如果这块不清楚的话可以移步深入 jsx章节。

这里再简单的回归下:

// jsx
class Hello extends Component {
  render() {
    return <div>Hello World</div>;
  }
}
// React.createElement
class Hello extends Component {
  render() {
    return React.createElement("div", null, `Hello World`);
  }
}

最终的代码都会被转化成 React.createElement的形式,只不过Babel帮助我们完成了自动转化。

因此,由于要通过 Babel 转化,而 Babel 在转化的时候会遵循下列的规则:

WARNING

Babel在编译时会判断 JSX 中组件的首字母。

  • 当首字母为小写时,其被认定为原生 DOM 标签createElement 的第一个变量被编译为字符串

  • 当首字母为大写时,其被认定为自定义组件createElement 的第一个变量被编译为对象

因此我们的自定义组件需要为大写。

上次更新时间: 2021-06-07 09:34:00