Wordpress:在 edit.js 中构建了 Gutenberg 自定义块,并在尝试查看页面时出现 useSelect 错误

问题描述 投票:0回答:1

这是我的错误:

error message

这是我的代码:

edit.js

import { __ } from '@wordpress/i18n';
import {
    useBlockProps,
    InspectorControls,
    PanelColorSettings
} from '@wordpress/block-editor';
import {
    PanelBody,
    PanelRow
} from '@wordpress/components';
import { useState } from '@wordpress/element';
import './editor.scss';
import {options, categories}from './container';
import { mapFile } from './app';
export default function Edit({ attributes, setAttributes }) {
    const blockProps = useBlockProps();
    const { backgroundColor, textColor } = attributes;

    const updateGroupId = (val) => {
        setAttributes({ GroupId: parseInt(val) });
    }
    const onChangeBackgroundColor = (BackgroundColor) => {
        setAttributes({ backgroundColor: BackgroundColor })
    }
    const onChangeTextColor = (TextColor) => {
        setAttributes({ textColor: TextColor })
    }   
    const stringArray = categories.map(JSON.stringify);
    const uniqueStringArray = new Set(stringArray);
    const uniqueArray = Array.from(uniqueStringArray, JSON.parse);
    const [selectedValue, setSelectedValue] = useState('vtalk');
    const handleSelectChange = (event) => {
          setSelectedValue(event.target.value);
          console.log(event.target.value);
        }
    const mapFile = options.filter((m, idx) => idx < 5 && m.category == selectedValue).map((m) => { return (<div class="blog-stamp"><img src={m.image} width="200" height="200" /><h3 class="stamp-title">{m.label}</h3><p class="stamp-excerpt">{m.content}</p><p class="button-parent"><a href={m.link} class="sfs-button" style={{ backgroundColor: backgroundColor, color: textColor }}>Read more</a></p></div>) });
    return (
        <div {...blockProps}>
            <InspectorControls>
                <PanelColorSettings
                    title={__('Button Color settings', 'sfs-block')}
                    initialOpen={false}
                    colorSettings={[
                        {
                            value: textColor,
                            onChange: onChangeTextColor,
                            label: __('Button Text color', 'sfs-block')
                        },
                        {
                            value: backgroundColor,
                            onChange: onChangeBackgroundColor,
                            label: __('Button Background color', 'sfs-block')
                        }
                    ]}
                />
                <PanelBody
                    title={__('category filter', 'sfs-block')}
                    initialOpen={true}
                >
                    <PanelRow>
                        <fieldset>
                        <select value={selectedValue} onChange={handleSelectChange}>
                                {uniqueArray.map((cat) => {
                                    return <option value={cat.category}>{cat.category}</option>
                                })}
                            </select>
                        </fieldset>
                    </PanelRow>
                </PanelBody>
            </InspectorControls>
            {console.log(uniqueArray)}
            <p class="blog-stamp-parent">{mapFile}</p>
            </div>

    );
} 

Save.js

import { useBlockProps } from '@wordpress/block-editor';
import { useState } from '@wordpress/element';
import {options} from './container';

export default function save({attributes}) {
    const [selectedValue] = useState('vtalk');
    const mapFile = options.filter((m, idx) => idx < 5 && m.category == selectedValue).map((m) => { return (<div class="blog-stamp"><img src={m.image} width="200" height="200" /><h3 class="stamp-title">{m.label}</h3><p class="stamp-excerpt">{m.content}</p><p class="button-parent"><a href={m.link} class="sfs-button" style={{ backgroundColor: backgroundColor, color: textColor }}>Read more</a></p></div>) });
    const { backgroundColor, textColor } = attributes;
    return (
        <div{ ...useBlockProps.save() }>
        <p class="blog-stamp-parent">{mapFile}</p>
        </div>
    );
}

这两个问题似乎是 selectedValue 没有从

edit.js
导入到
save.js
。另一个问题是 useState 没有从
edit.js
导入到
save.js

我不太确定如何处理这两个问题并解决它们。我希望这是一个简单的修复。

我是 React 的新手,所以任何帮助将不胜感激。预先感谢

javascript reactjs wordpress wordpress-gutenberg
1个回答
0
投票

要解决第一个问题,

selectedValue
应保存为块属性,以便可以在
save()
函数中访问它。查看您的代码,可以通过将
<select>
替换为 SelectControl 来简化,假设
categories
设置为标签/值对,然后
selectedValue
变为
groupId
。所选类别的整数值保存在块属性(
groupId
)中,以渲染所选选项的类别。

此外,在 React 中,CSS 类名称被指定为

className
而不是
class
- 这可以在所有
div
h3
p
a
image
元素上看到。虽然这会在控制台中触发警告,但最好解决此问题,以免导致其他问题,因为不应使用
class

请在下面找到更新的代码的所有相关部分,以便块正常运行、保存和渲染。示例数据非常简单,但希望能够指导您走上正确的道路,用实际数据实现这一点。

block.json 显示调整后的属性..

...
"attributes": {
        "backgroundColor": {
            "type": "string",
            "source": "attribute",
            "default": "#000000"
        },
        "textColor": {
            "type": "string",
            "source": "attribute",
            "default": "#FFFFFF"
        },
        "groupId": {
            "type": "integer",
            "source": "attribute",
            "default": 1
        }
    },
...

container.js 基于 edit.js 创建的示例数据+添加的 renderMapList() 函数

const options = [
    { label: 'one', content: 'apple', link: '#one', category: 1, image: 'https://placehold.co/200' },
    { label: 'two', content: 'banana', link: '#two', category: 1, image: 'https://placehold.co/200' },
    { label: 'three', content: 'orange', link: '#three', category: 1, image: 'https://placehold.co/200' },
    { label: 'four', content: 'carrot', link: '#four', category: 2, image: 'https://placehold.co/200' },
    { label: 'five', content: 'potato', link: '#five', category: 2, image: 'https://placehold.co/400' }
];

export const categories = [
    { value: 1, label: 'fruit' },
    { value: 2, label: 'vegetable' }
];

// Created a function to use in both edit.js and save.js for consistent rendering using attributes
export function renderMapFile(groupId, backgroundColor, textColor) {
    return options.filter((m, index) => index < 5 && m.category == groupId) 
    // category is compared to groupId; which is stored as attribute in block.json
        .map(({ image, label, content, link }, index) => {
            // Each child in a list should contain a unique "key", in this case index on <div>
            return (
                <div key={index} className="blog-stamp">
                    <img src={image} width="200" height="200" />
                    <h3 className="stamp-title">
                        {label}
                    </h3>
                    <p className="stamp-excerpt">
                        {content}
                    </p>
                    <p className="button-parent">
                        <a href={link} className="sfs-button" style={{ backgroundColor: backgroundColor, color: textColor }}>Read more</a>
                    </p>
                </div>
            )
        });
}

edit.js 简化为功能所需的基本基础知识,用 SelectControl

替换 select
import { __ } from '@wordpress/i18n';
import { useBlockProps, InspectorControls, PanelColorSettings } from '@wordpress/block-editor';
import { PanelBody, PanelRow, SelectControl } from '@wordpress/components';
import './editor.scss';
import { categories, renderMapFile } from './container';

export default function Edit({ attributes, setAttributes }) {
    const blockProps = useBlockProps();

    const { backgroundColor, textColor, groupId } = attributes;

    return (
        <div {...blockProps}>
            <InspectorControls>
                <PanelColorSettings
                    title={__('Button Color settings', 'sfs-block')}
                    initialOpen={false}
                    colorSettings={[
                        {
                            value: textColor,
                            onChange: (value) => setAttributes({ textColor: value }),
                            label: __('Button Text color', 'sfs-block')
                        },
                        {
                            value: backgroundColor,
                            onChange: (value) => setAttributes({ backgroundColor: value }),
                            label: __('Button Background color', 'sfs-block')
                        }
                    ]}
                />
                <PanelBody
                    title={__('category filter', 'sfs-block')}
                    initialOpen={true}
                >
                    <PanelRow>
                        <fieldset>
                            <SelectControl
                                value={groupId}
                                onChange={(value) => setAttributes({ groupId: value })}
                                options={categories}
                            />
                        </fieldset>
                    </PanelRow>
                </PanelBody>
            </InspectorControls>
            <div className="blog-stamp-parent">{renderMapFile(groupId, backgroundColor, textColor)}</div>
        </div>
    );
}

保存.js

import { useBlockProps } from '@wordpress/block-editor';
import { renderMapFile } from './container';

export default function save({ attributes }) {
    const { backgroundColor, textColor, groupId } = attributes;

    return (
        <div{...useBlockProps.save()}>
            <div className="blog-stamp-parent">
                 {renderMapFile(groupId, backgroundColor, textColor)}
            </div>
        </div>
    );
}
© www.soinside.com 2019 - 2024. All rights reserved.