从定制Gutenberg组件外部获取该组件的状态

时间:2019-01-08 作者:Sean

我已经在块编辑器中注册了一个侧栏组件。我想进入state 组件的(MyPlugin) 从该组件外部,在同一文件中的任意JavaScript中。是否可以通过访问状态,例如wp 对象

或者,是否有可能,使用props?

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

        // initial state
        this.state = {
            key: \'my_key\',
            value: \'\'
        }
    }

    render() {
        return el(
            PluginPostStatusInfo,
            {
                className: \'my-panel-class\'
            },
            el(
                TextControl,
                {
                    name: \'my_text_control_name\',
                    label: __( \'My label\', \'my-text-domain\' ),
                    value: this.state.value,
                    onChange: ( value ) => {
                        this.setState( {
                            value
                        })
                    }
                }
            )
        );
    }
}

registerPlugin( \'my-plugin\', {
    render: MyPlugin
} );

const myFunction = () => {
    // this function is hooked into an action elsewhere,
    // and needs to access the state of MyPlugin
}
我最终想做的是从一个单独的函数访问textbox的值。我不介意如何实现这一点,例如stateprops 或者其他方式。我想另一种方法是让组件在其更改时将其值写入全局变量,但这似乎有点笨拙。

2 个回复
最合适的回答,由SO网友:Alvaro 整理而成

为此,您需要使用redux存储。要注册您自己的,您可以按照documentation. 以下是实现您所寻求目标的最低要求。

首先,让我们给出初始状态对象中存储的“形状”:

const initial_state = {
    my_control: {
        value: ""
    },
};
让我们创建一个控制状态的减速器:

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;
};
如您所见,我们设置initial_state 对象,我们刚刚创建为状态的默认值。

现在,让我们添加一个更新存储的操作,将数据发送到reducer:

const actions = {
    updateMyControlValue(value) {
        return {
            type: "UPDATE_MY_CONTROL_VALUE",
            value
        };
    },
}
让我们添加一个从存储中获取数据的选择器:

const selectors = {
    getMyControlValue(state) {
        return state.my_control.value;
    },
};
现在,我们将使用前面的常量注册存储:

const { registerStore } = wp.data;

registerStore("my_plugin/my_store", {
    reducer,
    actions,
    selectors
});
现在商店已注册。我们将组件连接到存储,以获取my\\u控件的最新值并进行更新:

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);
这是一个简单的示例,但您可以查看文档上的链接,了解如何使用其他功能来增强存储(例如,使用控件和解析器)。

您还可以使用core stores 以及组件中的选择器和操作withSelectwithDispatch.

SO网友:Sean

我找到了一个解决方案,但我不确定这是否真的是想要的方法。我使用核心编辑器数据存储设置值,然后在函数中从中检索它。

onChange 在中回调MyPlugin, 除了设置状态,我还保存值:

onChange: ( value ) => {
    this.setState( {
        value
    })

    // set data in store
    wp.data.select(\'core/editor\').my_custom_key = value;
}
然后在我的函数中,我只是将其取出:

const myFunction = () => {
    var myData = wp.data.select(\'core/editor\').my_custom_key;

    // do stuff with myData...
}