在事件回调中使用选择-不按时检索值

时间:2021-10-13 作者:Lovor

我尝试在事件回调中使用useSelect,如中所述block editor handbook, 然而,由于检索值的时间比我需要的时间晚,所以我没有定义该值。我想我需要某种额外的异步函数来捕获检索时的值,或者这里没有描述其他机制吗?

Note that I am not using useSelect in a classical way with callback because value can\'t be retrieved upon component refresh, but on user action

这段代码应该检查,当选择某种类型的帖子时,然后检索它的特色图片,否则让用户选择图片。目前我只登录到控制台,因为我正在调试它。

SingleImage 是抽象的组件,它允许用户选择和替换图像。

import { useBlockProps, URLInput } from \'@wordpress/block-editor\';
import SingleImage from \'../../components/singleImage.jsx\'
import { useSelect } from \'@wordpress/data\';

import \'./editor.scss\';

export default function Edit({ attributes, setAttributes }) {
    const { getEntityRecord } = useSelect(\'core\');
    const urlInputSetter = (url, post) => {
        if (post && ! attributes.imgID) {
            if (post.type === \'virtualne-izlozbe\') {
                const record = getEntityRecord(\'postType\', \'virtualne-izlozbe\', post.id );
                if (record)
                    console.log(record.featured_media);
                else
                    console.log(\'empty\');
            }
        }
        setAttributes( { link: url, postTitle: (post && post.title) } )
    }

    return (
        <div { ...useBlockProps() }>
            <URLInput
                value={ attributes.link }
                onChange={ urlInputSetter }
                label="Link na objavu"
                className="post-link"
            />
            { attributes.postTitle && <div className="post-title">Slika vodi na objavu { attributes.postTitle }</div> }
            <SingleImage
                imgID={attributes.imgID}
                imgURL={attributes.imgURL}
                alt="Slika koja vodi na objavu"
                setImgIdAndUrl={(imgID, imgURL) => setAttributes({imgID, imgURL})}
                title="Izaberi sliku"
                help="Slika koja vodi na objavu"
            />

        </div>
    );
}

1 个回复
SO网友:Kalimah

您发布的文档中写道:

Don’t use useSelect this way when calling the selectors in the render function because your component won’t re-render on a data change.

import { useSelect } from \'@wordpress/data\';
 
function Paste( { children } ) {
    const { getSettings } = useSelect( \'my-shop\' );
    function onPaste() {
        // Do something with the settings.
        const settings = getSettings();
    }
    return <div onPaste={ onPaste }>{ children }</div>;
}
这基本上就是您使用的方式,这就是为什么您的组件在发生更改时会重新渲染。

您可以使用react挂钩(useState、useffect)来解决此问题。请参见下面的代码。我已经对代码进行了注释,以解释这些更改。(代码未测试)

import { useBlockProps, URLInput } from \'@wordpress/block-editor\';
import SingleImage from \'../../components/singleImage.jsx\';
import { useSelect } from \'@wordpress/data\';
const { useState, useEffect } = wp.element;
import \'./editor.scss\';

export default function Edit({ attributes, setAttributes }) {
    // Prepare state
    const [post, setPost] = useState();

    // useSelect with a callback, notice the third paramter
    const record = useSelect(
        (select) => {
            return select(\'core\').getEntityRecords(
                \'postType\',
                \'virtualne-izlozbe\',
                post.id
            );
        },
        // This is a dependency array, everytime the state of
        // "post" changes, useSelect callback will be called.
        [post]
    );

    // Perfom actions on state change
    useEffect(() => {
        // record value change, do someting
        if (record) {
            console.log(record.featured_media);
        } else {
            console.log(\'empty\');
        }
        // Dependency array, every time record changes the useEffect callback
        // will be called
    }, [record]);

    const urlInputSetter = (url, urlPost) => {
        if (urlPost && !attributes.imgID) {
            if (urlPost.type === \'virtualne-izlozbe\') {
                // Change state so the useSelect callback will be triggered
                setPost(urlPost);
            }
        }
        setAttributes({ link: url, postTitle: post && post.title });
    };

    return (
        <div {...useBlockProps()}>
            <URLInput
                value={attributes.link}
                onChange={urlInputSetter}
                label="Link na objavu"
                className="post-link"
            />
            {attributes.postTitle && (
                <div className="post-title">
                    Slika vodi na objavu {attributes.postTitle}
                </div>
            )}
            <SingleImage
                imgID={attributes.imgID}
                imgURL={attributes.imgURL}
                alt="Slika koja vodi na objavu"
                setImgIdAndUrl={(imgID, imgURL) =>
                    setAttributes({ imgID, imgURL })
                }
                title="Izaberi sliku"
                help="Slika koja vodi na objavu"
            />
        </div>
    );
}

相关推荐