本文介绍
网页由 DOM 元素构成。React DOM 并不是浏览器的 DOM,而是 React DOM 只是用来告诉浏览器如何创建 DOM 的方法。通常情况下,我们并不需要 React 就能创建出一个 DOM 元素,但是 React 创建与管理 DOM 的方式有组件化、虚拟 DOM 等更高层次的抽象,由此带来的优势是更快的渲染速度,以及更好的维护性,因此值得去尝试。
下面分别用 JavaScript 原生方法,React.createElement 方法,以及 JSX 方法来创建一个 div 元素:
html结构应该如下:
<div id="box">hello world</div>
JavaScript原生方法,没有过多需要解释的部分:
const box = document.createElement(‘div‘);
box.innerHTML = ‘hello world‘;
box.id = ‘box‘;
document.body.appendChild(box);
// 方法2:React.createElement
import React from ‘react‘;
import ReactDOM from ‘react-dom‘;
const Box = React.createElement("div", {id: "box"}, "hello world");
ReactDOM.render(Box, document.getElementById(‘root‘));
其中 createElement(type, props, children)
React.createElement(type, props, children)
。其中 children 可以是一个 React.createElement 列表
,也可以写成多个参数:
var child1 = React.createElement(‘li‘, null, ‘one‘);
var child2 = React.createElement(‘li‘, null, ‘two‘);
var content = React.createElement(‘ul‘, { className: ‘teststyle‘ }, [child1, child2]);
ReactDOM.render(
content,
document.getElementById(‘app‘)
);
// 或者
var child1 = React.createElement(‘li‘, null, ‘one‘);
var child2 = React.createElement(‘li‘, null, ‘two‘);
var content = React.createElement(‘ul‘, { className: ‘teststyle‘ }, child1, child2);
ReactDOM.render(
content,
document.getElementById(‘example‘)
);
这个使用方式是 React.createElement 使用方法的一种,它一共有7个重载方法,上面的使用方式的函数签名为:
function createElement<P extends {}>(
type: FunctionComponent<P> | ComponentClass<P> | string,
props?: Attributes & P | null,
...children: ReactNode[]
): ReactElement<P>;
其他重载方法见 React 源码,在实际开发中 React.createElement 用的比较少,因为可以直接 JSX 语法。
import React from ‘react‘;
import ReactDOM from ‘react-dom‘;
const Box = function () {
return (
<div id="box">hello world</div>
)
}
ReactDOM.render(Box, document.getElementById(‘root‘));
有 JSX 的地方,在文件开头就需要引入 React,因为实际上 JSX 是使用了 React.createElement,JSX 只是一个JS 的语法糖,所以需要引入 React 包,否则会报错。
react-dom
是一个把 React 代码渲染到网页端的包。如果在 Native 中渲染,就需要使用 React Native 的相关包。
const Box = function () {
return (
<div id="box">hello world</div>
)
}
上面这一段 JSX 语法糖会被编译为:
const Box = () => {
return React.createElement("div", {id: "box"}, "hello world");
}
使用 JSX 的一个限制是:在 JSX 中 html 代码第一层只能写一个元素。如果有多个标签(元素)并列,形成所谓的相邻JSX元素(adjacement jsx elements),就会报语法错误。通常这种多元素并列的情况,需要在它们外面包裹一层 div。
// error: Adjacent JSX elements must be wrapped in an enclosing tag
import React from ‘react‘;
import ReactDOM from ‘react-dom‘;
const title = (
<h1>Parallel elements demo</h1>
<p>Content</p>
);
ReactDOM.render(title, document.getElementById(‘root‘));
// success
import React from ‘react‘;
import ReactDOM from ‘react-dom‘;
const title = (
<div>
<h1>Parallel elements demo</h1>
<p>Content</p>
</div>
);
ReactDOM.render(title, document.getElementById(‘root‘));
对于 jsx 外层需要包裹一层 div,如果要突破这个限制,目前有两种方法:
(1) 返回数组
// 使用数组没有问题
import React from ‘react‘;
import ReactDOM from ‘react-dom‘;
const arr = [‘Adams‘, ‘Bill‘, ‘Charlie‘];
const Arr = () => {
return arr.map((item, index) => <p key={index}>{item}</p>);
};
ReactDOM.render(<Arr />, document.getElementById(‘root‘));
(2) 高阶组件(HOC)
div 去包裹并列元素的痛点是,我们可能并不需要这个多余的 div 标签,可能会破坏 html 结构,也许上层做了 flex,并不能有效的传递到这些并列标签上。
所以这里引入了用于辅助的高阶组件 hoc。虽然高阶组件的名字听起来很吓人,然而做的事情很简单,就是传递的作用。
// 突破JSX标签包裹限制:方法2 高阶组件
import React from ‘react‘;
import ReactDOM from ‘react-dom‘;
const Aux = props => props.children;
const box = (
<Aux>
<h1>Parallel elements demo</h1>
<p>Content</p>
</Aux>
);
ReactDOM.render(box, document.getElementById(‘root‘));
在上面这段代码中,const Aux = props => props.children
就是高阶组件。Aux 这个高阶组件的作用是把标签包括的内容进行传递和显示,查看最终 html 结构会发现 div 已经消失了,而且代码没有 div 也能正常。
在React 16.2 提供一个 Aux 功能,即 Fragment,但写成 <></>:
import React from ‘react‘;
import ReactDOM from ‘react-dom‘;
const title = (
<>
<div>hello</div>
<div>world</div>
</>
);
ReactDOM.render(title, document.getElementById(‘root‘));
一个初学者经常犯错的问题是将 React.createElement
返回值(类型为ReactElement)当作标签使用:
// ReactElement
const Header = (
<>
<div>hello</div>
<div>world</div>
</>
);
// Functional Component
const Card = () => {
return <div>hello</div>
}
// error
ReactDOM.render(<Header />, document.getElementById(‘root‘));
ReactDOM.render(Card, document.getElementById(‘root‘));
// success
ReactDOM.render(Header, document.getElementById(‘root‘));
ReactDOM.render(<Card />, document.getElementById(‘root‘));
原文:https://www.cnblogs.com/GManba/p/13300444.html