最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

block editor - Gutenberg get withState variable in save function

programmeradmin1浏览0评论

I'm not very familiar with React and Redux. I have a problem with Gutenberg to get the value of the withState variable within the save function. Here's my code:

edit( {attributes, setAttributes, className} ) {

    var link_text = attributes.link_text;
    var link_url = attributes.link_url;
    var svg_url = attributes.svg_url;
    var template_url = ww_blocks.templateUrl;
    var hasExternalURL = attributes.hasExternalURL;

    function onChangeLinkText ( content ) {
        setAttributes({link_text: content})
    }

    function onChangeLinkURL ( content ) {
        setAttributes({link_url: content})
    }

    setAttributes({svg_url: template_url + '/img/icons.svg#button-next'});

    const LinkToggleControl = withState( {
                hasExternalURL: false,
    } )( ( { hasExternalURL, setState } ) => (
        <ToggleControl
            label="Externer Link"
            help={ hasExternalURL ? 'Es ist ein externer Link.' : 'Kein externer Link.' }
            checked={ hasExternalURL }
            onChange={ () => setState( ( state ) => ( { hasExternalURL: ! state.hasExternalURL } ) ) }
        />
    ) );

        return ([
        <InspectorControls>
          <PanelBody title="Link Parameter">
            <div id="ww-container-inspector-control-wrapper">
              <label class="blocks-base-control__label" for="mce_1">Link Text</label>
              <TextControl
                onChange={onChangeLinkText} // onChange event callback
                value={link_text} // Input Binding
                />
              <label class="blocks-base-control__label" for="mce_2">Link URL</label>
              <TextControl
                onChange={onChangeLinkURL} // onChange event callback
                value={link_url} // Input Binding
                />
              <LinkToggleControl />
            </div>
          </PanelBody>
        </InspectorControls>,
        <div className={ className }>
          <a class="btn btn-std" href="#">
            <svg role="img" class="symbol" aria-hidden="true" focusable="false">
              <use href={svg_url}></use>
            </svg>
            <span>{link_text}</span>
          </a>
        </div>
    ]);
    },

    save( { attributes } ) {

        return (
        <a className="btn btn-std" href={attributes.link_url} target={ attributes.hasExternalURL ? '_blank' : '' } title={ attributes.hasExternalURL ? 'Seite öffnet in neuem Fenster' : '' }>
          <svg role="img" class="symbol" aria-hidden="true" focusable="false">
            <use href={attributes.svg_url}></use>
          </svg>
          <span>{attributes.link_text}</span>
        </a>
        );
    },
} );

I'm not very familiar with React and Redux. I have a problem with Gutenberg to get the value of the withState variable within the save function. Here's my code:

edit( {attributes, setAttributes, className} ) {

    var link_text = attributes.link_text;
    var link_url = attributes.link_url;
    var svg_url = attributes.svg_url;
    var template_url = ww_blocks.templateUrl;
    var hasExternalURL = attributes.hasExternalURL;

    function onChangeLinkText ( content ) {
        setAttributes({link_text: content})
    }

    function onChangeLinkURL ( content ) {
        setAttributes({link_url: content})
    }

    setAttributes({svg_url: template_url + '/img/icons.svg#button-next'});

    const LinkToggleControl = withState( {
                hasExternalURL: false,
    } )( ( { hasExternalURL, setState } ) => (
        <ToggleControl
            label="Externer Link"
            help={ hasExternalURL ? 'Es ist ein externer Link.' : 'Kein externer Link.' }
            checked={ hasExternalURL }
            onChange={ () => setState( ( state ) => ( { hasExternalURL: ! state.hasExternalURL } ) ) }
        />
    ) );

        return ([
        <InspectorControls>
          <PanelBody title="Link Parameter">
            <div id="ww-container-inspector-control-wrapper">
              <label class="blocks-base-control__label" for="mce_1">Link Text</label>
              <TextControl
                onChange={onChangeLinkText} // onChange event callback
                value={link_text} // Input Binding
                />
              <label class="blocks-base-control__label" for="mce_2">Link URL</label>
              <TextControl
                onChange={onChangeLinkURL} // onChange event callback
                value={link_url} // Input Binding
                />
              <LinkToggleControl />
            </div>
          </PanelBody>
        </InspectorControls>,
        <div className={ className }>
          <a class="btn btn-std" href="#">
            <svg role="img" class="symbol" aria-hidden="true" focusable="false">
              <use href={svg_url}></use>
            </svg>
            <span>{link_text}</span>
          </a>
        </div>
    ]);
    },

    save( { attributes } ) {

        return (
        <a className="btn btn-std" href={attributes.link_url} target={ attributes.hasExternalURL ? '_blank' : '' } title={ attributes.hasExternalURL ? 'Seite öffnet in neuem Fenster' : '' }>
          <svg role="img" class="symbol" aria-hidden="true" focusable="false">
            <use href={attributes.svg_url}></use>
          </svg>
          <span>{attributes.link_text}</span>
        </a>
        );
    },
} );
Share Improve this question edited Jul 7, 2020 at 9:15 Tom J Nowell 61k7 gold badges79 silver badges148 bronze badges asked Jul 7, 2020 at 9:06 jsjqueryreactjsjqueryreact 535 bronze badges 1
  • What are you trying to do that requires this? withState isn't a variable it's a function call – Tom J Nowell Commented Jul 7, 2020 at 9:19
Add a comment  | 

1 Answer 1

Reset to default 2

That is not how blocks work. If you want to save something, it must be a block attribute.

withState lets a function have internal state, so it's useful if you want to add toggle controls to your blocks UI, but it should not be used to store things that need to be saved. So you might use it to help build the UI for a block, hold temporary things, anything that doesn't need to be solved and can be eliminated. E.g. wether a panel is open or collapsed.

Further, if we ignore this, and try to use withState we run into several issues:

  • the state in the save function would not be the same state, so the value wouldn't carry over
  • the information would be in the HTML, but because it isn't a block attribute it would not be saved and the next time you opened the editor it would dissapear and need to be reset or the HTML would change
  • withState is meant to be used inside a React component, but the save method is intended for generating the final HTML to go in the database.

The fundamental problem here is that the LinkToggleControl is using local ephemeral state to store wether it's toggled or not, when it should be using setAttributes instead.

发布评论

评论列表(0)

  1. 暂无评论