Gutenberg does not render changes in array of objects meta
A post has a meta value which contains array of objects.
Seems like the values printed in a loop in fields do not render a changes unless I send a new meta key with dispatch.
This does not work, If i change the values in the fields printed in loop the values would not be rendered back to the fields and the changes typed will be ignored
LinksControl = withDispatch(
(dispatch) => {
return {
handleLinksChange: (links, property, arrayIndex, value) => {
links[arrayIndex][property] = value;
links = links.slice(0);
let meta = {meta: {links: links}}
dispatch('core/editor').editPost(meta)
}
}
}
)(LinksControl);
This works:
LinksControl = withDispatch(
(dispatch) => {
return {
handleLinksChange: (links, property, arrayIndex, value) => {
links[arrayIndex][property] = value;
links = links.slice(0);
let meta = {meta: {links: links,newKey:''}}
dispatch('core/editor').editPost(meta)
}
}
}
)(LinksControl);
Seems like the "newKey" somehow does render a change and the links array values do updated back the fields typed.
But when sending the "links" itself React/Gutenberg for some reason do not detect a change and do not render the values back to the fields.
I also noticed that in case 1 even without adding a "newKey" to meta object, if I start typing in a diffrent regular field with regular flat meta (not array) then the array fields values will render and update on change.
What is the correct way to fix this issue?
Adding the "newKey" feels like a hack and I’m looking for the correct way to render the values on change.
Full code snippet for reference:
import {registerPlugin} from 'wordpress user/plugins';
import {PluginDocumentSettingPanel} from 'wordpress user/edit-post';
const {RadioControl, TextControl, SelectControl} = wp.components
const {withSelect, withDispatch} = wp.data
let LinksControl = ({links, handleLinksChange}) => {
return <div><h2>Links</h2>
{links.map((link, arrayIndex) => (
<div><h6>Link {arrayIndex + 1}:</h6>
<TextControl
label="Set url"
value={links[arrayIndex].url}
onChange={link => handleLinksChange(links, 'url', arrayIndex, link)}
/>
<SelectControl
label="Set Index"
value={links[arrayIndex].index}
onChange={(linkIndex) => {
handleLinksChange(links, 'index', arrayIndex, linkIndex)
}}
options={getRangeArray(1, 10)}
/>
</div>
))
}
</div>
};
LinksControl = withSelect(
(select) => {
return {
links: select('core/editor').getEditedPostAttribute('meta')['links']
}
}
)(LinksControl);
LinksControl = withDispatch(
(dispatch) => {
return {
handleLinksChange: (links, property, arrayIndex, value) => {
links[arrayIndex][property] = value;
links = links.slice(0);
let meta = {meta: {links: links}}
dispatch('core/editor').editPost(meta)
}
}
}
)(LinksControl);
const getRangeArray = (min, max) => {
const arr = [];
for (let i = min; i <= max; i++) {
arr.push(i);
}
return arr.map(rank => {
return {label: rank, value: rank}
})
}
const CustomFieldsPanel = () => {
return <PluginDocumentSettingPanel
name="custom-panel"
title="Custom fields"
className="custom-panel"
>
<LinksControl/>
</PluginDocumentSettingPanel>
};
registerPlugin('plugin-document-setting-panel-demo', {
render: CustomFieldsPanel
})
Leave an answer