Wordpress Gutenberg:前端的 React 组件
Posted
技术标签:
【中文标题】Wordpress Gutenberg:前端的 React 组件【英文标题】:Wordpress Gutenberg: React components on front end 【发布时间】:2019-01-17 03:52:25 【问题描述】:Gutenberg 仍然很新,但我仍然希望有人遇到此问题并找到解决方案。
我使用 create-guten-block 来样板化一个项目并创建了一个测试块。我遇到的问题是,当我尝试使用 React 组件在前端修改状态时,什么也没有发生。通过 save() 可以很好地加载组件,但是当您尝试执行简单的操作(例如切换列表)时,前端仍然对状态更改没有响应。我还要注意 create-guten-block 不加载任何前端 JS,所以我将编译后的 javascript 换成前端加载,但仍然无法正常工作。
这是我从 Codecademy 中提取的一些代码,作为一个简单的测试示例。当您选择一个名称时,它会更改sibling.js 中的文本以显示该名称。该代码在 create-react-app 中运行良好,但在前端作为 Gutenberg 中的一个块什么也不做:
block.js
import Parent from './parent';
// More code here
save: function( props )
return (
<div>
<Parent />
</div>
);
,
parent.js
import React from 'react';
import Child from './child';
import Sibling from './sibling';
export class Parent extends React.Component
constructor(props)
super(props);
this.state = name: 'Frarthur' ;
this.changeName = this.changeName.bind(this);
changeName(newName)
this.setState(
name: newName
);
render()
return (
<div>
<Child onChange=this.changeName />
<Sibling name=this.state.name />
</div>
);
;
child.js
import React from 'react';
export class Child extends React.Component
constructor(props)
super(props);
this.handleChange = this.handleChange.bind(this);
handleChange(e)
const name = e.target.value;
this.props.onChange(name);
render()
return (
<div>
<select
id="great-names"
onChange=this.handleChange>
<option value="Frarthur">Frarthur</option>
<option value="Gromulus">Gromulus</option>
<option value="Thinkpiece">Thinkpiece</option>
</select>
</div>
);
sibling.js
import React from 'react';
export class Sibling extends React.Component
render()
const name = this.props.name;
return (
<div>
<h1>Hey, my name is name!</h1>
<h2>Don't you think name is the prettiest name ever?</h2>
<h2>Sure am glad that my parents picked name!</h2>
</div>
);
【问题讨论】:
【参考方案1】:Gutenberg 很棒,但不能对它的文档说同样的话。它就像任何其他 Wordpress 文档一样,过于冗长、组织不善和健谈。我认为它与领土和目标消费者有关。
我花了一些时间和几次通过手册来了解什么是块。资源稀缺,人们通常会将块与其在编辑器中的屏幕视觉表示混淆。
话虽如此,让我们从古腾堡积木开始。 Gutenberg 块是优雅的短代码,如下所示:
<!-- wp:paragraph "key": "value" -->
<p>Welcome to the world of blocks.</p>
<!-- /wp:paragraph -->
这些短代码被编辑器渲染成反应组件以进行可视化表示。
请记住这里的短代码[gallery id="123" size="medium"]
,它可以通过 tinymce 插件呈现为可视化表示,您将在编辑器窗口中看到完整的、正常运行的画廊。想法是一样的,只是这次古腾堡编辑器将略有不同的短代码呈现为视觉表示。
现在,混乱出现了,因为 WordPress 文档也将这些视觉表示作为块来处理。但是整个渲染-序列化-解析-重新渲染周期的真实来源是一个,那就是这些所谓的“优雅短代码”,其余的是这些短代码采用的不同形式和表示。比如说,在编辑器上下文中,它是一个渲染的反应组件,在前端它只是普通的 html。
edit
函数的返回元素将决定块在编辑器窗口中的显示方式:
<!-- language: lang-js -->
registerBlockType(«NAMESPACE/BLOCK_NAME»,
edit: function(props)
// Should return a react element
)
了解块的生命周期以更好地了解它们至关重要。让我们从头开始:
当您点击组件面板中的块图标时,save
函数的返回将被渲染并序列化并插入到页面中。
<!-- language: lang-js -->
registerBlockType("NAMESPACE/BLOCK_NAME",
save: function(props)
// Should return a react element
)
save
函数应该返回一个react 元素,该元素将由react 渲染并由块序列化器序列化 并作为block 插入到帖子内容中。你可以查看serializer.js
,了解 React 元素是如何序列化为块的1。
<!-- wp:image -->
<figure class="wp-block-image"><img src="source.jpg" /></figure>
<!-- /wp:image -->
如果是动态块,save
函数会返回null
,所以不会有内容。块看起来像这样:
<!-- wp:latest-posts "postsToShow":4,"displayPostDate":true /-->
注意自我关闭评论:
在blocks grammar中,第一个称为静态块(_Block_Balanced_),第二个称为动态块(_Block_Void_)。
请务必注意,静态块包含渲染内容和属性对象。对于动态块,应在块注册期间将render_callback
提供给register_block_type
函数。
因此,当请求the_content
时,服务器会获取the_content
并在响应请求之前将其传递给多个filters。
在这个阶段,属性将从静态块中剥离,并且内容将被返回,因为静态块本身已经包含了它们的内容。对于动态块,将调用 render_callback 并将其返回值作为块内容返回。这就是文档中 某种程度上完全同构3 的意思。您可以在 Wordpress 核心中查看render_block
函数。
当您通过古腾堡的视觉元素编辑块时,该块将重新进行重新序列化过程,并且将根据您所做的更改将新的视觉表示绘制到页面上。
<!-- wp:paragraph "key": "value" -->
<p>Welcome to the world of blocks.</p>
<!-- /wp:paragraph -->
单击发布按钮后,按照文档所述,此序列化数据或行数据将保存到数据库中。
假设您在保存后关闭页面。下次打开它时,块解析器将解析保存的块,并将视觉表示绘制到页面上。你可以看看解析器2。
在解析过程中,块标记将根据save
函数进行验证。如果您在两次编辑之间更改了save
函数的返回,则先前保存的块标记将无效或deprecated。您可以通过在 registerBlockType
的块设置中提供升级路径来更新已弃用的代码。但是,您更改 edit
函数不会产生任何影响,因为它控制块在编辑器屏幕上的显示方式。
升级路径只是一个具有函数和属性的对象数组。已弃用的块将由该数组中的每个元素根据优先级进行检查,如果块与新版本兼容,则将进行迁移,如果不兼容则返回旧版本。
现在来回答您的问题,当请求前端服务器上的页面时,会向您发送完整格式的 html。所以,前面你得到的是静态 html,而不是 react 元素。
因此,实际上save
函数与前端无关,只是创建包裹在块 cmets <!-- wp:image --><!-- /wp:image -->
中的静态 html,这在编辑内容时发生。在前端服务 the_content
时,它永远不会运行或咨询。
为了增加交互性,您必须编写专门针对前端的代码,就像在古腾堡之前所做的那样。
您可以在编辑器窗口中使用更多工具和选项按钮切换到代码编辑器,以纯文本形式查看the_content
,更新按钮。
从前端的角度来看,创建the_content
时使用tinymce编辑器还是古腾堡编辑器还是纯html没有区别。
注册块时,您可以将另一个 javascript 文件排入队列或使用您通过 enqueue_block_assets
排入队列的文件。
要使用 React,您必须使用 ReactDOM 将组件安装到文档上。好消息是 Wordpess 已经在全局空间中提供了 React 和 ReactDOM,但是您需要在对脚本进行排队时指出依赖关系。
【讨论】:
抱歉花了这么长时间将其标记为最佳答案。谢谢你这么彻底! 您能举例说明如何使用 ReactDOM 将组件安装到文档上吗?我有类似的问题,在保存方法中,我想使用 React 并捕获诸如 onClick 之类的事件。 @Ognyan 当然。常量元素 =你好,世界
; ReactDOM.render(element, document.getElementById('root'));确保您的 html 文件中有 id 属性为“root”的元素。你在这里有更详细的解释reactjs.org/docs/rendering-elements.html。如果您以通常的方式将 Gutenberg 与 wordpress 一起使用,react 可能不是一个好主意。 @SnnSnn 这应该放在save
函数中吗?我需要在前端(用户应该单击按钮)而不是在编辑器中捕获事件!
@Ognyan 如果你有保存功能,这意味着块内容将在前端呈现,只需使用vanilla js或jquery,就像你以前一样。【参考方案2】:
据我了解,Gutenburg 仅支持等式的 编辑器 端的交互性。是的,你在 React 中定义了 view 端,但是这个视图在保存帖子的时候被渲染为静态标记,然后只有这个静态标记被传递给客户端(读者)。
好处是您可以免费获得“服务器端渲染”,并且您的客户端不需要 React 即可查看帖子。缺点是如果你想做客户端交互,它超出了古腾堡的范围,你必须找到自己的方式。
【讨论】:
谢谢贝西!在过去的三个月里,我已经很好地处理了它,并且只提供了与 jQuery 的前端交互性。不理想,但已经被 Wordpress 加入队列并且可以正常工作。 你能举例说明如何使用 ReactDOM 将组件安装到文档上吗?我有类似的问题,在保存方法中,我想使用 React 并捕获诸如 onClick 之类的事件。以上是关于Wordpress Gutenberg:前端的 React 组件的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Wordpress 中列出和重新排列或操作 Gutenberg 块类别
以编程方式触发 Wordpress Gutenberg “转换为块”
scss WordPress Gutenberg专栏SCSS样式