admin管理员组文章数量:1199187
I've been banging my head on this for a bit now.
I'm trying to create a simple wordpress block that fetches custom post types from the rest api, then displays the fetched posts via react. It only needs to do this, and requires no other editor functionality.
However, I'm a bit of a react/wp noob and I may be fundamentally misunderstanding how wordpress react functions, as I can't seem to get anywhere.
Here is my code so far:
class oupSeriesBlock extends Component {
constructor(props) {
super(props);
this.state = {data: []};
}
getOupSeries() {
console.log('mounted');
apiFetch({
path: 'wp/v2/oup_series'
}).then((response) => {
this.state = {data: response}
console.log(this.state);
})
}
componentDidMount() {
this.getOupSeries();
}
render() {
return(
<div>
Test
{this.state.data.length > 0 ? this.state.data.map(data => <div>{data.id}</div>) : 'empty'}
</div>
)
}
}
registerBlockType('cb/oup-series', {
title: 'OUP Book Series',
apiVersion: 2,
category: 'cb-layout',
icon: 'book-alt',
description: 'Shows list of OUP book series',
keywords: ['book', 'series', 'oup'],
edit: () => {
const blockProps = useBlockProps();
return (
<div {...blockProps}>
<div>OUP Series List</div>
</div>
)
},
save: oupSeriesBlock
});
The block is available and rendering without error but is not displaying any data, only 'Test' is rendered.
The rest route is definitely functioning correctly as I've tested it, but componentDidMount()
is never being called.
this.state.data.map
also works correctly when constructed with dummy data.
I've read through multiple examples and tutorials, but I'm having trouble applying them to my problem, if anyone could help it would be greatly appreciated.
I've been banging my head on this for a bit now.
I'm trying to create a simple wordpress block that fetches custom post types from the rest api, then displays the fetched posts via react. It only needs to do this, and requires no other editor functionality.
However, I'm a bit of a react/wp noob and I may be fundamentally misunderstanding how wordpress react functions, as I can't seem to get anywhere.
Here is my code so far:
class oupSeriesBlock extends Component {
constructor(props) {
super(props);
this.state = {data: []};
}
getOupSeries() {
console.log('mounted');
apiFetch({
path: 'wp/v2/oup_series'
}).then((response) => {
this.state = {data: response}
console.log(this.state);
})
}
componentDidMount() {
this.getOupSeries();
}
render() {
return(
<div>
Test
{this.state.data.length > 0 ? this.state.data.map(data => <div>{data.id}</div>) : 'empty'}
</div>
)
}
}
registerBlockType('cb/oup-series', {
title: 'OUP Book Series',
apiVersion: 2,
category: 'cb-layout',
icon: 'book-alt',
description: 'Shows list of OUP book series',
keywords: ['book', 'series', 'oup'],
edit: () => {
const blockProps = useBlockProps();
return (
<div {...blockProps}>
<div>OUP Series List</div>
</div>
)
},
save: oupSeriesBlock
});
The block is available and rendering without error but is not displaying any data, only 'Test' is rendered.
The rest route is definitely functioning correctly as I've tested it, but componentDidMount()
is never being called.
this.state.data.map
also works correctly when constructed with dummy data.
I've read through multiple examples and tutorials, but I'm having trouble applying them to my problem, if anyone could help it would be greatly appreciated.
Share Improve this question asked May 11, 2022 at 11:16 elliott_lelliott_l 133 bronze badges 3 |1 Answer
Reset to default 1This is because when your block was rendered for save the API call had not finished. Save components do not run on the frontend.
render() {
return(
<div>
Test
{this.state.data.length > 0 ? this.state.data.map(data => <div>{data.id}</div>) : 'empty'}
</div>
)
}
The purpose of a save component is to take your blocks attributes, and turn them into static HTML to be saved in the post content. None of the code in your save component executes on the frontend. Your save component cannot have side effects or lifecycle methods.
In order to implement fetching posts from the API endpoint when the block is viewed by frontend users, you need to enqueue a javascript file, identify all the places your block is used, and fetch the data. This is not different to when a shortcode has frontend javascript. The main difference here is that WordPress has hooks and filters to let you only enqueue the blocks frontend assets when it's actually used.
In summary:
- Save components can't have state, side effects, or pull data from external sources such as editor state or remote APIs
- Save components don't run on the frontend
- Only the static serialised output of a save component is saved, not the react component itself
- A save component must always return the same output given the same block attributes, or it is built incorrectly and will fail block validation
- Use functional components so that you can use newer versions of the block API and hooks such as
useBlockProps
for better performance and features. - frontend javascript requires a separate frontend JS file to be enqueued
本文标签: javascriptVery simple wordpress block to display posts from an api call
版权声明:本文标题:javascript - Very simple wordpress block to display posts from an api call 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738593413a2101648.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
useEffect
hook which can be used to fetch the posts more efficiently. Likewise it is an antipattern to talk directly to the REST API to fetch posts, there are more efficient cached APIs already built into the block editor for listing entities – Tom J Nowell ♦ Commented May 11, 2022 at 11:42