在Gutenberg中保存帖子后的其他类“未定义”

时间:2021-01-05 作者:Shafayat Alam

The problem: 每当我输入东西时Advanced->Additional Classes 在古腾堡编辑器中,保存页面/帖子并刷新,这些类就会消失。我已登录props.className 在里面edit 作用当我在Advanced->Additional Classes 领域输入类名并刷新页面后保存帖子时出现问题。在我创建的其他块中,我采用了完全相同的方法,它们工作得很好。

The Code:

    edit: (props) => {
        const {attributes, setAttributes} = props;
        const headingBgOverlay = Util.getBgOverlay(attributes, \'heading\');
        const bodyBgOverlay = Util.getBgOverlay(attributes, \'body\');

        useEffect(() => {
            setAttributes({blockId: Util.guidGenerator()});
        }, []);

        useEffect(() => {
            console.log(props)
            console.log(props.className)
            console.log(attributes.className)
            setAttributes({headingBgOverlay});
            setAttributes({bodyBgOverlay});
        }, [attributes]);
        return (
            <Fragment>
                <Fragment>
                    <style>
                        {listIconCss(attributes)}
                    </style>
                    <div className={"atbs atbs-pricing-table " + props.className}
                         id={\'atbs-pricing-table-\' + attributes.blockId}>
                        <div className="plan"
                             style={{...planCss(attributes)}}>
                            <div className="head" style={{...titleCss(attributes)}}>
                                <RichText style={{...titleTypographyCss(attributes)}} tagName="h2" className={\'m-0\'}
                                          value={attributes.title}
                                          onChange={(title) => setAttributes({title})}
                                          placeholder={__(\'Plan name\', \'attire-blocks\')}/>
                            </div>
                            <div className=\'atbs_pricing_table_body\'>
                                <RichText
                                    style={{...descrCss(attributes)}}
                                    className={\'description\'} tagName="p" value={attributes.description}
                                    onChange={(description) => setAttributes({description})}
                                    placeholder={__(\'Description...\', \'attire-blocks\')}/>
                                <div className="price" style={{...priceCss(attributes)}}>
                                    <RichText style={{fontSize: (attributes.priceFontSize / 2) + \'px\'}}
                                              className={\'symbol\'}
                                              tagName="span" value={attributes.symbol}
                                              onChange={(symbol) => setAttributes({symbol})}
                                              placeholder={__(\'$\')}/>
                                    <RichText className={\'amount\'}
                                              tagName="span" value={attributes.price}
                                              onChange={(price) => setAttributes({price})}
                                              placeholder={__(\'99.99\')}/>

                                    {attributes.recurring && <RichText
                                        style={{fontSize: `${attributes.descrFontSize}${attributes.descrFontSizeUnit}`}}
                                        tagName="span" value={attributes.recurringTime}
                                        className="recurring"
                                        onChange={(value) => setAttributes({recurringTime: value})}
                                        placeholder={__(\'/month\', \'attire-blocks\')}/>}

                                </div>
                                {attributes.showFeatures && <RichText
                                    style={{...listCss(attributes)}}
                                    multiline="li"
                                    tagName="ul"
                                    className="features"
                                    onChange={(nextValues) => setAttributes({features: nextValues})}
                                    value={attributes.features}
                                    placeholder={__(\'Write list…\', \'attire-blocks\')}
                                />}

                                <InnerBlocks allowedBlocks={[\'attire-blocks/buttons\']}
                                             template={[[\'attire-blocks/buttons\', {
                                                 buttonAlignment: \'center\'
                                             }]]}
                                             templateLock="all"/>
                            </div>
                        </div>
                    </div>
                </Fragment>
            </Fragment>
        );
    },
    save: ({attributes, className}) => {
        //const {attributes} = props;
        return (
            <Fragment>
                <style>
                    {listIconCss(attributes)}
                </style>
                <div className={"atbs atbs-pricing-table " + className}
                     id={\'atbs-pricing-table-\' + attributes.blockId}>
                    <div className="plan"
                         style={{...planCss(attributes)}}>
                        {attributes.title &&
                        <div className="head" style={{...titleCss(attributes)}}>
                            <RichText.Content style={{...titleTypographyCss(attributes)}} tagName="h2" className={\'m-0\'}
                                              value={attributes.title}/>
                        </div>}
                        <div className=\'atbs_pricing_table_body\'>
                            {attributes.description &&
                            <RichText.Content
                                style={{...descrCss(attributes)}}
                                className={\'description\'} tagName="p" value={attributes.description}/>}
                            <div className="price" style={{...priceCss(attributes)}}>
                                <RichText.Content style={{fontSize: (attributes.priceFontSize / 2) + \'px\'}}
                                                  className={\'symbol\'} tagName="span" value={attributes.symbol}/>
                                <RichText.Content
                                    style={{
                                        color: attributes.bodyTextColor,
                                        fontSize: (attributes.priceFontSize) + \'px\'
                                    }}
                                    className={\'amount\'}
                                    tagName="span" value={attributes.price}/>
                                {attributes.recurring && <RichText.Content
                                    style={{fontSize: `${attributes.descrFontSize}${attributes.descrFontSizeUnit}`}}
                                    className="recurring"
                                    tagName="span" value={attributes.recurringTime}/>}
                            </div>
                        </div>
                        {attributes.showFeatures && <RichText.Content
                            style={{...listCss(attributes)}}
                            className={\'features\'}
                            tagName="ul" value={attributes.features}/>}
                        <InnerBlocks.Content/>
                    </div>
                </div>
            </Fragment>
        );
    }
});

2 个回复
SO网友:Shafayat Alam

经过大约一个小时的反复试验,我发现<Fragment> 是罪魁祸首。但我还是不明白为什么!将其替换为<div> 修复了它。

现在代码如下所示:

    edit: (props) => {
        const {attributes, setAttributes} = props;
        const headingBgOverlay = Util.getBgOverlay(attributes, \'heading\');
        const bodyBgOverlay = Util.getBgOverlay(attributes, \'body\');

        useEffect(() => {
            setAttributes({blockId: Util.guidGenerator()});
        }, []);

        useEffect(() => {
            console.log(props)
            console.log(props.className)
            console.log(attributes.className)
            setAttributes({headingBgOverlay});
            setAttributes({bodyBgOverlay});
        }, [attributes]);
        return (
                <div>
                    <style>
                        {listIconCss(attributes)}
                    </style>
                    <div className={"atbs atbs-pricing-table " + props.className}
                         id={\'atbs-pricing-table-\' + attributes.blockId}>
                        <div className="plan"
                             style={{...planCss(attributes)}}>
                            <div className="head" style={{...titleCss(attributes)}}>
                                <RichText style={{...titleTypographyCss(attributes)}} tagName="h2" className={\'m-0\'}
                                          value={attributes.title}
                                          onChange={(title) => setAttributes({title})}
                                          placeholder={__(\'Plan name\', \'attire-blocks\')}/>
                            </div>
                            <div className=\'atbs_pricing_table_body\'>
                                <RichText
                                    style={{...descrCss(attributes)}}
                                    className={\'description\'} tagName="p" value={attributes.description}
                                    onChange={(description) => setAttributes({description})}
                                    placeholder={__(\'Description...\', \'attire-blocks\')}/>
                                <div className="price" style={{...priceCss(attributes)}}>
                                    <RichText style={{fontSize: (attributes.priceFontSize / 2) + \'px\'}}
                                              className={\'symbol\'}
                                              tagName="span" value={attributes.symbol}
                                              onChange={(symbol) => setAttributes({symbol})}
                                              placeholder={__(\'$\')}/>
                                    <RichText className={\'amount\'}
                                              tagName="span" value={attributes.price}
                                              onChange={(price) => setAttributes({price})}
                                              placeholder={__(\'99.99\')}/>

                                    {attributes.recurring && <RichText
                                        style={{fontSize: `${attributes.descrFontSize}${attributes.descrFontSizeUnit}`}}
                                        tagName="span" value={attributes.recurringTime}
                                        className="recurring"
                                        onChange={(value) => setAttributes({recurringTime: value})}
                                        placeholder={__(\'/month\', \'attire-blocks\')}/>}

                                </div>
                                {attributes.showFeatures && <RichText
                                    style={{...listCss(attributes)}}
                                    multiline="li"
                                    tagName="ul"
                                    className="features"
                                    onChange={(nextValues) => setAttributes({features: nextValues})}
                                    value={attributes.features}
                                    placeholder={__(\'Write list…\', \'attire-blocks\')}
                                />}

                                <InnerBlocks allowedBlocks={[\'attire-blocks/buttons\']}
                                             template={[[\'attire-blocks/buttons\', {
                                                 buttonAlignment: \'center\'
                                             }]]}
                                             templateLock="all"/>
                            </div>
                        </div>
                    </div>
                </div>
        );
    },
    save: ({attributes, className}) => {
        //const {attributes} = props;
        return (
            <div>
                <style>
                    {listIconCss(attributes)}
                </style>
                <div className={"atbs atbs-pricing-table " + className}
                     id={\'atbs-pricing-table-\' + attributes.blockId}>
                    <div className="plan"
                         style={{...planCss(attributes)}}>
                        {attributes.title &&
                        <div className="head" style={{...titleCss(attributes)}}>
                            <RichText.Content style={{...titleTypographyCss(attributes)}} tagName="h2" className={\'m-0\'}
                                              value={attributes.title}/>
                        </div>}
                        <div className=\'atbs_pricing_table_body\'>
                            {attributes.description &&
                            <RichText.Content
                                style={{...descrCss(attributes)}}
                                className={\'description\'} tagName="p" value={attributes.description}/>}
                            <div className="price" style={{...priceCss(attributes)}}>
                                <RichText.Content style={{fontSize: (attributes.priceFontSize / 2) + \'px\'}}
                                                  className={\'symbol\'} tagName="span" value={attributes.symbol}/>
                                <RichText.Content
                                    style={{
                                        color: attributes.bodyTextColor,
                                        fontSize: (attributes.priceFontSize) + \'px\'
                                    }}
                                    className={\'amount\'}
                                    tagName="span" value={attributes.price}/>
                                {attributes.recurring && <RichText.Content
                                    style={{fontSize: `${attributes.descrFontSize}${attributes.descrFontSizeUnit}`}}
                                    className="recurring"
                                    tagName="span" value={attributes.recurringTime}/>}
                            </div>
                        </div>
                        {attributes.showFeatures && <RichText.Content
                            style={{...listCss(attributes)}}
                            className={\'features\'}
                            tagName="ul" value={attributes.features}/>}
                        <InnerBlocks.Content/>
                    </div>
                </div>
            </div>
        );
    }
});

SO网友:Sally CJ

看起来是最外面的<Fragment> 是罪魁祸首。但我还是不明白为什么!将其替换为<div> 修复了它。

如果你在WordPress 5.6.0, 您不需要更换<Fragment> 具有<div>. :)

这是因为WordPress 5.6.0实际上block API version 2 引入了一个名为useBlockProps 应该在block\'s edit() and save() functions — 你可以在我提供的链接上阅读更多内容,但基本上useBlockProps, 你可以使用Fragment 作为最外层的包装。

基于1的工作示例here:

import { registerBlockType } from \'@wordpress/blocks\';
import { useBlockProps, RichText } from \'@wordpress/block-editor\';
import { Fragment } from \'@wordpress/element\';

registerBlockType( \'my-plugin/foo-block\', {
    // Required; use the block API version 2
    apiVersion: 2,

    title: \'Foo Block\',
    category: \'design\',

    attributes: {
        content: {
            type: \'array\',
            source: \'children\',
            selector: \'p\',
        },
    },

    // In edit(), use useBlockProps()
    edit: ( props ) => {
        const { attributes: { content }, setAttributes, className } = props;
        const blockProps = useBlockProps();

        const onChangeContent = ( newContent ) => {
            setAttributes( { content: newContent } );
        };

        return (
            <Fragment>
                <div className={ blockProps.className }>
                    <RichText
                        { ...blockProps }
                        tagName="p"
                        onChange={ onChangeContent }
                        value={ content }
                    />
                    <p>{ \'Back-end: \' + blockProps.className }</p>
                </div>
            </Fragment>
        );
    },

    // In save(), use useBlockProps.save()
    save: ( props ) => {
        const blockProps = useBlockProps.save();

        return (
            <Fragment>
                <div className={ blockProps.className }>
                    <RichText.Content
                        { ...blockProps }
                        tagName="p"
                        value={ props.attributes.content }
                    />
                    <p>{ \'Front-end: \' + blockProps.className }</p>
                </div>
            </Fragment>
        );
    },
} );
如上所述,为了获得额外的CSS类(以及其他/自动生成的CSS类),我使用blockProps.className 而不是props.className 这给了我们undefined.

相关推荐