Getting a custom Gutenberg component’s state from outside that component

To do so you need to use a redux store. To register your own you can follow the steps in the documentation. Here is the minimum that should achieve what you are looking for.

First, lets give the “shape” of the store in the initial state object:

const initial_state = {
    my_control: {
        value: ""
    },
};

Lets create a reducer that manipulates the state:

const reducer = (state = initial_state, action) => {
    switch (action.type) {
        case "UPDATE_MY_CONTROL_VALUE": {
            return {
                ...state,
                my_control: {
                    ...state.my_control,
                    value: action.value
                }
            };
        }
    }

    return state;
};

As you can see, we set the initial_state object we just created as the default value of the state.

Now lets add an action which updates the store, sending data to the reducer:

const actions = {
    updateMyControlValue(value) {
        return {
            type: "UPDATE_MY_CONTROL_VALUE",
            value
        };
    },
}

Lets add a selector that gets the data from the store:

const selectors = {
    getMyControlValue(state) {
        return state.my_control.value;
    },
};

And now we will register the store with the previous constants:

const { registerStore } = wp.data;

registerStore("my_plugin/my_store", {
    reducer,
    actions,
    selectors
});

Now the store is registered. We will connect the component to the store to get the latest value of my_control and to update it:

const { Component } = wp.element;
const { TextControl } = wp.components;
const { compose } = wp.compose;
const { withDispatch, withSelect } = wp.data;

class Text extends Component {
    render() {
        const { value, updateMyControlValue } = this.props;

        return (
            <TextControl
                value={value}
                onChange={updateMyControlValue}
            />
        );
    }
}

export default compose([
    withDispatch((dispatch, props) => {
        // This function here is the action we created before.
        const { updateMyControlValue } = dispatch("my_plugin/my_store");

        return {
            updateMyControlValue
        };
    }),
    withSelect((select, props) => {
        // This function here is the selector we created before.
        const { getMyControlValue } = select("my_plugin/my_store");

        return {
            value: getMyControlValue()
        };
    }),
])(Text);

This is a simple example, but you can take a look at the link on the documentation to see how you can use other functionality to enhance the store (for example, with controls and resolvers).

Also you can make use the core stores and their selectors and actions inside your component’s withSelect and withDispatch.

Leave a Comment