rest api - Custom meta POST request fired twice when updating a post in Gutenberg

admin2025-06-04  2

I have made a feature similar in behaviour to Revision Notes, but for Gutenberg. It is a Gutenberg sidebar plugin which adds a text field where users can write an edit summary when they edit a post, which is then stored as post meta data when the post is saved.

I am new to React but using this tutorial as a basis I put together this code to make a request to a REST endpoint I defined in my plugin when the post is saved with the contents of the edit summary text box:

var el = wp.element.createElement;
var __ = wp.i18n.__;
var Component = wp.element.Component;
var PluginPostStatusInfo = wp.editPost.PluginPostStatusInfo;
var TextControl = wpponents.TextControl;
var registerPlugin = wp.plugins.registerPlugin;
var withSelect = wp.data.withSelect;

class My_Edit_Summary_Plugin extends Component {
    constructor() {
        super( ...arguments );

        this.state = {
            key: 'my_edit_summary',
            // edit summary always initially empty
            value: ''
        }
    }

    /**
     * Update post meta using REST API.
     */
    static getDerivedStateFromProps( nextProps, state ) {
        if ( nextProps.isSaving && !nextProps.isAutoSaving && !nextProps.isPublishing ) {
            if ( nextProps.revisionId ) {
                wp.apiRequest( { path: `/my-plugin/v1/update-meta?id=${nextProps.revisionId}`, method: 'POST', data: state } ).then(
                    ( data ) => {
                        return data;
                    },
                    ( err ) => {
                        return err;
                    }
                );
            }
        }
    }

    render() {
        return el(
            PluginPostStatusInfo,
            {
                className: 'my-edit-summary-panel'
            },
            el(
                TextControl,
                {
                    name: 'my_revision_post_edit_summary',
                    label: __( 'Edit summary', 'my-plugin' ),
                    help: __( 'Briefly summarise your changes', 'my-plugin' ),
                    value: this.state.value,
                    onChange: ( value ) => {
                        this.setState( {
                            value
                        })
                    }
                }
            )
        );
    }
}

/**
 * Give current post IDs and status flags to My_Edit_Summary_Plugin object.
 */
const HOC = withSelect( ( select, { forceIsSaving } ) => {
    const {
        getCurrentPostId,
        getCurrentPostLastRevisionId,
        isSavingPost,
        isPublishingPost,
        isAutosavingPost
    } = select( 'core/editor' );

    return {
        postId: getCurrentPostId(),
        revisionId: getCurrentPostLastRevisionId(),
        isSaving: forceIsSaving || isSavingPost(),
        isAutoSaving: isAutosavingPost(),
        isPublishing: isPublishingPost()
    };
} )( My_Edit_Summary_Plugin );

registerPlugin( 'my-edit-summary-plugin', {
    render: HOC
} );

The higher-order component is needed to grab the revision id (required by my REST endpoint). The /my-plugin/v1/update-meta REST endpoint saves the metadata using update_metadata, and this part works as expected. The problem I have is that the AJAX request is made twice. If I add console.log(nextProps); under the line if ( nextProps.revisionId ) { above, I see two console messages in quick succession when I click "Update" in the editor:

Object { postId: 420, revisionId: 426, isSaving: true, isAutoSaving: false, isPublishing: false }
Object { postId: 420, revisionId: 427, isSaving: true, isAutoSaving: false, isPublishing: false }

This has the effect that the previous version of the post (revisionId == 426) has its metadata updated as well as the new version. I only want to set the meta data of the new version (i.e. revisionId == 427).

I'd like to know if anyone can see what the problem is, but also whether anyone can think of a better way to save the meta data. It seems like this code is much more complicated than it should be, just to save a single text field. I have seen some mention of withDispatch to handle post updates. Perhaps this might be a better way to approach this?

转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1749040663a315853.html

最新回复(0)