作为一个思想实验,如果我要createElement为 JSX编写自己的实现,那么对隐式上下文的支持会是什么样的?
特别是,我无法弄清楚在 JSXcreateElement签名的有限方式下,不同子树的上下文是如何独立的。(在最近的版本中,React 的上下文处理似乎变得更加复杂;我最感兴趣的是早期版本看似更直接的机制。)
这可用于自动确定航向级别,例如:
<Section title="Hello World">
<Card title="Details" />
</Section>
<Card title="Example" />
Run Code Online (Sandbox Code Playgroud)
HereCard将通过依赖于类似的东西分别自动生成<h3>和。<h2>context.headingLevel
这是一个非常好的问题,它展示了创建 React Elements 与实际执行渲染函数(.render类组件的方法或简单的功能组件的主体)的概念有多么不同。
在 JSX 本身(只是React.createElement(\xe2\x80\xa6))中,\xe2\x80\x98s 根本没有 \xe2\x80\x9ccontext\xe2\x80\x9d 的概念。仅当组件被渲染时它才存在。实际实现 Context API 确实是 React Renderer(例如 React DOM 或 React Native)的职责。
如果您删除了存储状态和更新 UI 的功能,您将得到一个最小的 React 实现,仅 \xe2\x80\x9crenders 一次 \xe2\x80\x9d,但完全可以理解手头的问题。
\n每次 React 渲染器需要渲染一个 React Elements 树(例如用 JSX 构建的树)时,它都会传递每个元素并将其转换为 DOM 结构,但是当它遇到组件节点(不是 \xe2\x80\x9cnative\xe2 \x80\x9d 元素)需要渲染它以获得其React Element 子树,并与其交换原始节点。
\n在这个特定时刻,React 可以跟踪哪些 Context 值传递给哪些组件,因为它正在遍历树。
\n因此,要直接回答您的问题,您可以\xe2\x80\x99t 在\xe2\x80\x9c元素创建阶段\xe2\x80\x9d 中实现上下文,在 JSX 实现中,您需要在后续阶段中执行此操作你可以遍历这棵树。
\n如果你试图构建一个 \xe2\x80\x9cimmediate JSX\xe2\x80\x9d 你可能有这样的东西:
\nfunction createElement(type, props, ...children) {\n props = { children, ...props };\n\n if (typeof type === 'function') {\n return type(props);\n } else {\n return { type, props };\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n在这种情况下,您将无法实现类似于 context 的 API,因为执行顺序是先内后外:
\nconst div = createElement('div', {}, createElement(Card, {}));\n// identical to\nconst card = createElement(Card, {}); // inner, and then\xe2\x80\xa6\nconst div = createElement('div', {}, card); // outer\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
125 次 |
| 最近记录: |