I tried building my own custom gallery gutenberg block as shown here to get more familiar with the block structure. Putting all the code into a single file works fine, but when I try to split it up in edit.js and save.js, it returns this error upon trying to add images to it: "Uncaught TypeError: setAttributes is not a function"
I wasn't able to resolve this, what's the issue?
attributes in block.json
"attributes": {
"images" : {
"type": "array"
}
},
edit.js
/**
* Retrieves the translation of text.
*
* @see https://developer.wordpress.org/block-editor/reference-guides/packages/packages-i18n/
*/
import { __ } from '@wordpress/i18n';
/**
* React hook that is used to mark the block wrapper element.
* It provides all the necessary props like the class name.
*
* @see https://developer.wordpress.org/block-editor/reference-guides/packages/packages-block-editor/#useblockprops
*/
import {
useBlockProps,
MediaUpload
} from '@wordpress/block-editor';
import {
Button
} from '@wordpress/components';
//import {registerBlockType} from "@wordpress/blocks";
/**
* Lets webpack process CSS, SASS or SCSS files referenced in JavaScript files.
* Those files can contain any CSS code that gets applied to the editor.
*
* @see https://www.npmjs.com/package/@wordpress/scripts#using-css
*/
import './editor.scss';
/**
* The edit function describes the structure of your block in the context of the
* editor. This represents what the editor will render when the block is used.
*
* @see https://developer.wordpress.org/block-editor/reference-guides/block-api/block-edit-save/#edit
*
* @return {WPElement} Element to render.
*/
export default function Edit(attributes, className, setAttributes) {
const blockProps = useBlockProps();
// Getting the images of the array
const {images = [] } = attributes;
// to remove image from gallery
const removeImage = (removeImage) => {
//filter images
const newImages = images.filter( (image) => {
// if current image is equal to removeImage, image will be returend
if(image.id != removeImage.id) {
return image;
}
});
//save new state
setAttributes({
images: newImages,
})
}
//Display the images
const displayImages = (images) => {
return (
//Loop through images
images.map((image) => {
return (
<div className="gallery-item-container">
<img className='gallery-item' src={image.url} key={ images.id } />
<div className='remove-item' onClick={() => removeImage(image)}><span class="dashicons dashicons-trash"></span></div>
<div className='caption-text'>{image.caption[0]}</div>
</div>
)
})
)
}
//JSX to return
return (
<>
<div {...blockProps}>
<div className='gallery-grid'>
{displayImages(images)}
</div>
<br/>
<MediaUpload
onSelect={(media) => setAttributes({
images: [...images,...media],
})
}
type="image"
multiple={true}
gallery={true}
value={images}
render={({open}) => (
<Button className="select-images-button is-button is-default is-large" onClick={open}>
Add images
</Button>
)}
/>
</div>
</>
);
}
(attributes, className, setAttributes)
for your function arguments? This is very weird, and not what the examples show, I've never seen an example that didn't use{}
to destructure the propsuseState
call before realising I'd used{}
instead of[]
it happens to the best of us