admin管理员组文章数量:1130349
I've registered a sidebar component in the block editor. I'd like to access the state of the component (MyPlugin) from outside of that component, in some arbitrary JavaScript in the same file. Is it possible to access the state via e.g. the wp object?
Or, is it possible, and would it be better to do this using 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
}
What I'd ultimately like to do is access the textbox's value from a separate function. I don't mind how this is achieved, e.g. with state or props or some other means. I guess another approach would be to have the component write its value into a global variable when it changes, but that seems a bit clunky.
I've registered a sidebar component in the block editor. I'd like to access the state of the component (MyPlugin) from outside of that component, in some arbitrary JavaScript in the same file. Is it possible to access the state via e.g. the wp object?
Or, is it possible, and would it be better to do this using 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
}
What I'd ultimately like to do is access the textbox's value from a separate function. I don't mind how this is achieved, e.g. with state or props or some other means. I guess another approach would be to have the component write its value into a global variable when it changes, but that seems a bit clunky.
2 Answers
Reset to default 5To 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 } = wpponents;
const { compose } = wppose;
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.
I found a solution, but I'm not sure it's really the intended way to do this. I use the core editor datastore to set the value, then retrieve it from there in my function.
In the onChange callback in MyPlugin, in addition to setting the state I also save the value:
onChange: ( value ) => {
this.setState( {
value
})
// set data in store
wp.data.select('core/editor').my_custom_key = value;
}
then in my function I just grab it out:
const myFunction = () => {
var myData = wp.data.select('core/editor').my_custom_key;
// do stuff with myData...
}
I've registered a sidebar component in the block editor. I'd like to access the state of the component (MyPlugin) from outside of that component, in some arbitrary JavaScript in the same file. Is it possible to access the state via e.g. the wp object?
Or, is it possible, and would it be better to do this using 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
}
What I'd ultimately like to do is access the textbox's value from a separate function. I don't mind how this is achieved, e.g. with state or props or some other means. I guess another approach would be to have the component write its value into a global variable when it changes, but that seems a bit clunky.
I've registered a sidebar component in the block editor. I'd like to access the state of the component (MyPlugin) from outside of that component, in some arbitrary JavaScript in the same file. Is it possible to access the state via e.g. the wp object?
Or, is it possible, and would it be better to do this using 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
}
What I'd ultimately like to do is access the textbox's value from a separate function. I don't mind how this is achieved, e.g. with state or props or some other means. I guess another approach would be to have the component write its value into a global variable when it changes, but that seems a bit clunky.
- i guess not. the state is local. maybe InnerBlocks are the right for your requirements: github/WordPress/gutenberg/tree/master/packages/editor/src/… so you could nest two blocks.. – André Kelling Commented Jan 8, 2019 at 10:50
-
@AndréKelling, I've edited the question to say I'm happy to achieve this in any other way that's possible, so if the
stateis not available, perhapspropscan be used. – Sean Commented Jan 8, 2019 at 10:52 -
if you need that value inside the react components or subcomponents
stateandpropsare the way to go. but if you need that data in an independent custom JS script your solution looks very good! – André Kelling Commented Jan 8, 2019 at 11:53
2 Answers
Reset to default 5To 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 } = wpponents;
const { compose } = wppose;
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.
I found a solution, but I'm not sure it's really the intended way to do this. I use the core editor datastore to set the value, then retrieve it from there in my function.
In the onChange callback in MyPlugin, in addition to setting the state I also save the value:
onChange: ( value ) => {
this.setState( {
value
})
// set data in store
wp.data.select('core/editor').my_custom_key = value;
}
then in my function I just grab it out:
const myFunction = () => {
var myData = wp.data.select('core/editor').my_custom_key;
// do stuff with myData...
}
本文标签: pluginsGetting a custom Gutenberg component39s state from outside that component
版权声明:本文标题:plugins - Getting a custom Gutenberg component's state from outside that component 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://it.en369.cn/questions/1749031752a2305787.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。


stateis not available, perhapspropscan be used. – Sean Commented Jan 8, 2019 at 10:52stateandpropsare the way to go. but if you need that data in an independent custom JS script your solution looks very good! – André Kelling Commented Jan 8, 2019 at 11:53