问题是class ShowPosts
getPosts()
内部的setState没有被调用,我不知道为什么。 class SelectedPost
getOptions()
的工作原理和基本相同的代码。
我之前已经做过一些小型的React项目,但这是我第一次尝试在WP Gutenberg中创建一个块。
const { __ } = wp.i18n;
const { registerBlockType } = wp.blocks;
const { InspectorControls } = wp.editor;
const { SelectControl } = wp.components;
const { Component } = wp.element;
registerBlockType( 'pluginName/news', {
title: __('Show latest news'),
icon: 'tagcloud',
category: 'pluginCategory',
attributes: {
content: {
type: 'array',
source: 'children',
selector: 'p',
},
title: {
type: 'string',
selector: 'h2'
},
link: {
type: 'string',
selector: 'a'
},
selectedPost: {
type: 'number',
default: 0,
},
},
edit: SelectedPost,
save: ShowPosts
});
class SelectedPost extends Component {
static getInitialState (selectedPost) {
return {
posts: [],
selectedPost: selectedPost,
post: {}
};
}
constructor () {
super(...arguments);
this.state = this.constructor.getInitialState(this.props.attributes.selectedPost);
this.getOptions = this.getOptions.bind(this);
this.onChangeSelectPost = this.onChangeSelectPost.bind(this);
this.getOptions();
}
getOptions () {
wp.api.loadPromise.done(() => {
return (new wp.api.collections.Posts()).fetch().then((posts) => {
if (this.state.selectedPost !== 0) {
const post = posts.find((item) => {
return item.id == this.state.selectedPost
});
this.setState({ post, posts });
} else {
this.setState({ posts });
}
});
});
}
onChangeSelectPost (value) {
const post = this.state.posts.find((item) => {
return item.id == parseInt(value)
});
this.setState({ selectedPost: parseInt(value), post });
this.props.setAttributes({
selectedPost: parseInt(value)
});
}
render () {
let options = [ { value: 0, label: __('Select a news item') } ],
title = __('Displays latest news');
this.props.className += ' loading';
if (this.state.posts.length > 0) {
const loading = __('We have ' + this.state.posts.length + ' news items. %c');
if (this.state.post.title !== undefined) {
output = loading.replace('%c', '<a href="' + this.state.post.link + '">' + this.state.post.title.rendered + '</a> is being focused.');
} else {
output = loading.replace('%c', 'None is chosen.');
}
this.state.posts.forEach((post) => {
options.push({ value: post.id, label: post.title.rendered });
});
} else {
output = __('No news found. Please create some first.');
}
return [
<InspectorControls>
<div>
<h2>{ title }</h2>
<SelectControl onChange={ this.onChangeSelectPost } value={ this.props.attributes.selectedPost } label={ __('Select a news item to focus, leave empty to focus latest.') } options={ options } />
</div>
</InspectorControls>
,
<div dangerouslySetInnerHTML={ { __html: output } }></div>
]
}
}
class ShowPosts extends Component {
static getInitialState (selectedPost) {
return {
posts: [],
selectedPost: selectedPost,
post: {}
};
}
constructor () {
super(...arguments);
this.state = this.constructor.getInitialState(this.props.attributes.selectedPost);
this.getPosts = this.getPosts.bind(this);
this.getPosts();
}
getPosts () {
wp.api.loadPromise.done(() => {
return (new wp.api.collections.Posts()).fetch().then((posts) => {
this.setState({ posts }, () => console.log('Not called'));
});
});
}
pushedPost () {
return (
<div className="news-item">
<h2 dangerouslySetInnerHTML={{ __html: this.state.selectedPost.attributes.title}}></h2>
<div dangerouslySetInnerHTML={{ __html: this.state.selectedPost.attributes.content}}></div>
</div>
);
}
showPosts () {
const postItems = this.state.posts.forEach((post) => {
return <h2>{ post.rendered }</h2>
});
return postItems;
}
render () {
return (
<div className={ this.props.className }>
{ this.showPosts() }
</div>
);
}
}