前言
在前端的 React 面试中,基本都会涉及到 React 工作原理这一重要内容。快速且深入地掌握 React 工作原理,能够显著提高面试的通过率。正因如此,本系列将通过实现极为简单的 =mini react 来深入探究 React 的工作原理,期望能够持之以恒,与大家携手学习、共同进步。
JSX 语法与 React 元素
JSX 语法
其表现形式类似于<span>hello {name}</span>这样的语法糖。本质上,它是一种语法糖,在编译打包后会被 Babel 编译成 React.createElement,用于创建 React 元素。
React 元素
本质上是一个 JSON 对象,是由 React.createElement 函数所返回的对象。其结构大致如下,核心属性包括 type 和 props 等。
interface IReactElement {
type: string;
props?: {
className?: string,
style?: CSSProperties,
children?: IReactElement | IReactElement[],
}
}
开发阶段 - jsx
const Counter = () => {
const [count, setCount] = useState(0);
return (
<div>
<span>{count}</span>
<button onClick={() => setCount(count + 1)}>+</button>
<button onClick={() => setCount(count - 1)}>-</button>
</div>
);
};
编译阶段 - createElement
const Counter = (props) => {
const [count, setCount] = useState(0);
return createElement('div', {
children: [
createElement('span', { children: count }),
createElement('button', { children: '+', onClick: () => setCount(count + 1) }),
createElement('button', { children: '-', onClick: () setCount(count - 1) }),
]
}, count, createElement('div', null, props.name));
}
jsx 语法本质是 createElement 语法糖
源码实现
function createElement(type, props,...children) {
return {
type,
props: {
...props,
children: children.map((child) => {
return typeof child === 'object'? child : createTextElement(child)
})
}
}
}
// 如果传入的是纯文字,不想转成 innerText 模式,因此需要 createTextElement
function createTextElement(text) {
return {
type: 'TEXT_ELEMENT',
props: {
nodeValue: text,
children: []
}
}
}
export {
createElement
};