发布于 2026-01-06 0 阅读
0

仅使用 ES5 特性创建 React 组件

仅使用 ES5 特性创建 React 组件

这篇文章只是想友好地提醒大家,React 本质上就是 JavaScript。即使没有构建步骤,也可以直接使用它。用它创建一个简单的交互式组件也完全没问题。而且,如果你不想用 ES6+,也完全可以不用。

快速回顾一下 createElement 函数

React 公开了一个名为 createElement 的函数,它是每个组件的核心。JSX 实际上是语法糖,它会被转换成React.createElement函数调用。它看起来像这样:

React.createElement(
    'tagName',       // HTML tag name or a custom component 
    props,           // HTML attributes, custom properties, events, etc...
    children         // a string or a list of components or almost anything
);
Enter fullscreen mode Exit fullscreen mode

无状态组件

这类组件只接收props并返回一个 React 元素。它们不管理自身状态,也没有生命周期方法。它们非常适合展示来自其他来源的数据。无需任何构建步骤,它看起来可能像这样:

function Welcome(props) {
    return React.createElement('div', null, 'Hello, ' + props.name);
}

ReactDOM.render(Welcome({ name: 'world' }), container);
Enter fullscreen mode Exit fullscreen mode

类组件

这些组件可以管理自身的内部状态并拥有生命周期方法。但问题在于,在 ES5 中我们不能再使用 ` classcomponent` 关键字来创建组件,而是需要模仿这种行为。

首先我们需要处理继承问题。通常情况下,我们会使用 `@Return`class MyComponent extends React.Component来实现继承。但我们将另辟蹊径,通过用 ` prototype@Return` 中的对象覆盖组件对象来“强制”继承React.Component,如下所示:

function MyComponent(props) {
    React.Component.constructor.call(this);

    // ... code
}

MyComponent.prototype = Object.create(React.Component.prototype);
Enter fullscreen mode Exit fullscreen mode

与我们的无状态组件不同的是,我们调用React.Component构造函数时传入了自定义组件的上下文,并且确保原型来自 `<property>` 标签React.Component。这样一来,我们的组件现在就可以使用生命周期方法和 `setState` 方法了。

示例代码

现在有了这些新知识,我们可以创建一些组件,而无需设置构建步骤,也不必过多担心浏览器兼容性。让我们做一个简单的计时器:

var container   = document.getElementById('app');

// h is short for hyperscript and it makes everything a little bit easier
var h           = React.createElement;

// This is how we inherit methods like setState from React.Component
Timer.prototype = Object.create(React.Component.prototype);

function Timer(props) {
  React.Component.constructor.call(this);
  var self = this;

  self.state = { seconds: 0 };

  self.tick = function() {
    self.setState(function(prevState) {
      return { seconds: prevState.seconds + 1 };
    });
  };

  self.componentDidMount = function() {
    self.interval = setInterval(self.tick, 1000);
  };

  self.componentWillUnmount = function() {
     clearInterval(self.interval);
  };

  self.render = function() {
    return h('div', null, 'seconds: ', self.state.seconds);
  }
}

ReactDOM.render(h(Timer), container);
Enter fullscreen mode Exit fullscreen mode

请注意,我在这里将this上下文赋值给一个self变量,以避免使用bindFunction 原型的方法。为了保持一致性,我到处都使用了这种方法,尽管我认为只有在使用方法self.tick会导致上下文丢失的情况下才需要这样做thissetInterval

最后一件事

人们一开始往往忽略的一点是,元素的子元素也是参数。你可以传递组件、字符串、对象或函数。归根结底,它们children都是 prop。

让我给你展示一下。

结论

这种方法可行,而且也没那么糟糕。这说明你可以使用传统的 script 标签将 React 嵌入到任何网站中。另一个好处是,React 组件本质上是函数调用,你可以做任何你能想到的事情。真的,你可以做任何事,包括搬起石头砸自己的脚,所以要小心。

其他资源

待办事项列表示例、
计时器示例、
无需构建步骤的 React
、React 只是 JavaScript


感谢您的阅读。如果您觉得这篇文章有用,并想支持我的创作,请考虑在ko-fi.com/vonheikemen上给我打赏。

请我喝杯咖啡

文章来源:https://dev.to/vonheikemen/creating-react-components-using-only-es5-features-52a1