wordpress - Wordpress Gutenberg:前端的 React 组件
问题描述
Gutenberg 仍然很新,但我仍然希望有人遇到这个问题并找到解决方案。
我使用 create-guten-block 对项目进行样板化并创建了一个测试块。我遇到的问题是,当我尝试使用 React 组件在前端修改状态时,什么也没有发生。通过 save() 可以很好地加载组件,但是当您尝试执行简单的操作(例如切换列表)时,前端仍然对状态更改没有响应。我还要注意 create-guten-block 不加载任何前端 JS,所以我将编译后的 javascript 换成在前端加载,但仍然无法让它工作。
这是我从 Codecademy 中提取的一些代码,作为一个简单的测试示例。当您选择一个名称时,它会更改sibling.js 中的文本以显示该名称。该代码在 create-react-app 中运行良好,但在前端作为 Gutenberg 中的块什么也不做:
块.js
import { Parent } from './parent';
// More code here
save: function( props ) {
return (
<div>
<Parent />
</div>
);
},
父.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>
);
}
}
兄弟.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>
);
}
}
解决方案
古腾堡很棒,但不能对它的文档说同样的话。它就像任何其他 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 渲染并由块序列化器序列化并作为块插入到帖子内容中。您可以检查serializer.js
React 元素如何序列化为块1。
<!-- wp:image -->
<figure class="wp-block-image"><img src="source.jpg" alt="" /></figure>
<!-- /wp:image -->
如果是动态块,save
函数会返回null
,所以没有内容。块看起来像这样:
<!-- wp:latest-posts {"postsToShow":4,"displayPostDate":true} /-->
注意自我关闭评论:
在块语法中,第一个称为静态块(_Block_Balanced_),第二个称为动态块(_Block_Void_)。
需要注意的是,静态块包含渲染内容和属性对象。对于动态块,render_callback
应register_block_type
在块注册期间提供功能。
因此,当the_content
被请求时,服务器会在响应请求之前获取the_content
并通过几个过滤器。
在此阶段,将从静态块中剥离属性并返回内容,因为静态块本身已包含其内容。对于动态块,将调用 render_callback 并将其返回值作为块内容返回。这就是他们在文档中以某种方式完全同构的3的意思。render_block
您可以在 Wordpress 核心中签出功能。
当您通过gutenberg 的视觉元素编辑块时,该块将再次经历重新序列化过程,并且将根据您所做的更改将新的视觉表示绘制到页面上。
<!-- wp:paragraph {"key": "value"} -->
<p>Welcome to the world of blocks.</p>
<!-- /wp:paragraph -->
单击发布按钮后,此序列化数据或行数据,如文档所述,将保存到数据库中。
假设您在保存后关闭页面。下次打开它时,块解析器将解析保存的块,并将视觉表示绘制到页面上。你可以看看解析器2。
在解析期间,将针对save
函数验证块标记。如果您save
在两次编辑之间更改了函数的返回,则先前保存的块标记将无效或已弃用。您可以通过在您的块设置中提供升级路径来更新已弃用的代码registerBlockType
。但是,您更改edit
功能不会产生任何影响,因为它控制块在编辑器屏幕上的显示方式。
升级路径只是一个具有函数和属性的对象数组。不推荐使用的块将由该数组上的每个元素根据优先级进行检查,如果块与新版本兼容,将被迁移,如果不是旧版本,则返回。
现在提出您的问题,当请求前端服务器上的页面时,将向您发送完整的 html。所以,在前面你得到的是静态 html,而不是反应元素。
因此,实际上save
功能与前端无关,只是创建包含在块注释中的静态 html <!-- wp:image --><!-- /wp:image -->
,这在编辑内容时发生。the_content
在前端服务时从不运行或咨询它。
为了增加交互性,您必须编写专门针对前端的代码,就像在古腾堡之前所做的那样。
您可以通过使用更多工具和选项按钮在编辑器窗口中the_content
切换到代码编辑器来查看其纯文本形式,更新按钮旁边的垂直省略号。
从前端的角度来看,在创建the_content
.
这取决于您将另一个 javascript 文件排入队列或使用您enqueue_block_assets
在注册块时通过的那个。
要使用 React,您必须使用 ReactDOM 将组件安装到文档上。好消息是 Wordpess 已经在全局空间中提供了 React 和 ReactDOM,但是您需要在对脚本进行排队时指出依赖关系。
推荐阅读
- python-3.x - 定期将数据流式传输到 Azure Blob 存储
- google-sheets - 如何使用 Google Sheets (v4) API getByDataFilter 返回特定的数据行?
- javascript - Visual Studio Live 服务器响应更新,但 github 的真实托管网站没有
- azure - 使用 Java SDK 为 Azure Blob 存储生成签名 URL
- javascript - ES6中for循环的作用范围是什么?
- angular - TypeScript/Angular:向路由器中的数据属性添加接口
- java - Java HttpClient 实现 Curl .pem 文件
- powershell - 无法在 powershell 中选择变量的列名
- spring - Spring,JPA,Hibernate,按预期数量递增/递减变量
- python - 如何处理python中的巨型列表/矩阵?(不可分块)