ReactJS - 不使用JSX的React

JSX是什么?

在我们深入探讨不使用JSX的React之前,让我们先了解一下JSX是什么。JSX,或JavaScript XML,是JavaScript的一个语法扩展,它看起来类似于HTML。它与React一起使用,用来描述UI应该是什么样子。然而,JSX并不是使用React的要求。我们可以不使用JSX来使用React,这正是我们将在本教程中探讨的内容。

ReactJS - React Without JSX

为什么不使用JSX?

你可能会想,“既然JSX这么常见,我们为什么还想不使用它?”这是个好问题!有几个原因:

  1. 学习核心概念:了解不使用JSX的React可以让你更深入地理解这个库。
  2. 构建工具限制:有些构建环境可能不支持JSX编译。
  3. 个人偏好:有些开发者只是更喜欢编写纯JavaScript。

使用React.createElement()创建元素

使用React而不使用JSX的核心是React.createElement()函数。这个函数实际上就是JSX编译后的结果,我们只是省略了中间人!

让我们从一个简单的例子开始:

const element = React.createElement(
'h1',
{className: 'greeting'},
'Hello, world!'
);

在这个例子中,我们正在创建一个带有类名'greeting'的h1元素,并包含文本内容'Hello, world!'。让我们分解一下参数:

  1. 第一个参数('h1')指定了我们想要创建的元素类型。
  2. 第二个参数({className: 'greeting'})是一个包含元素属性的对象。
  3. 第三个参数('Hello, world!')是元素的内容。

如果我们用JSX来写,它看起来会像这样:

const element = <h1 className="greeting">Hello, world!</h1>;

看看JSX多么紧凑!但别担心,随着练习,不使用JSX创建元素会变得习惯成自然!

嵌套元素

现在,让我们尝试一些更复杂的。创建一个包含两个子元素的div怎么样?

const element = React.createElement(
'div',
null,
React.createElement('h1', null, 'Welcome'),
React.createElement('p', null, '这是一个段落。')
);

这创建了一个与以下结构等价的内容:

<div>
<h1>Welcome</h1>
<p>这是一个段落。</p>
</div>

注意我们是如何嵌套createElement调用来创建子元素的。null参数是我们需要时放置属性的地方。

创建组件

组件是React应用程序的构建块。让我们创建一个不使用JSX的简单函数式组件:

function Welcome(props) {
return React.createElement(
'h1',
null,
'欢迎,' + props.name
);
}

要使用这个组件,我们会这样做:

const element = React.createElement(Welcome, {name: 'Alice'});

这等同于JSX:

const element = <Welcome name="Alice" />;

处理事件

在不使用JSX的React中处理事件与使用JSX非常相似。让我们创建一个在点击时记录消息的按钮:

function handleClick() {
console.log('按钮被点击!');
}

const button = React.createElement(
'button',
{onClick: handleClick},
'点击我'
);

在这里,我们将handleClick函数作为onClick属性传递给按钮元素。

条件渲染

在不使用JSX的情况下,条件渲染会更加冗长,但仍然完全可能:

function Greeting(props) {
if (props.isLoggedIn) {
return React.createElement('h1', null, '欢迎回来!');
} else {
return React.createElement('h1', null, '请注册。');
}
}

const element = React.createElement(
Greeting,
{isLoggedIn: true}
);

列表和键

在不使用JSX渲染列表时,我们需要显式使用Array.map()

const numbers = [1, 2, 3, 4, 5];

const listItems = numbers.map((number) =>
React.createElement('li', {key: number.toString()}, number)
);

const list = React.createElement('ul', null, listItems);

注意我们仍然在使用key属性,这对于React的协调过程至关重要。

方法表格

下面是一个总结我们讨论的关键方法的表格:

方法 描述 示例
React.createElement() 创建一个React元素 React.createElement('div', null, 'Hello')
Array.map() 转换数组元素 numbers.map(n => React.createElement('li', null, n))
React.render() 将React元素渲染到DOM ReactDOM.render(element, document.getElementById('root'))

结论

虽然JSX确实使得编写React代码更加直观和可读,但了解如何不使用JSX的React可以让你更深入地理解底层的运作。这就像在学习自动挡汽车之前先学习手动挡汽车一样 - 它给了你更多的控制和理解过程的能力。

记住,无论你使用JSX与否,React的核心原则保持不变。组件、属性、状态和虚拟DOM都以相同的方式工作。JSX只是让编码过程更甜蜜的语法糖!

所以,下次你在调试React应用程序时看到React.createElement()编译后的代码,你就会确切地知道发生了什么。快乐编码,愿你的React元素总是正确渲染!

Credits: Image by storyset