Я не могу найти ответ на этот вопрос, который я могу понять

У меня есть вкладки и блок вкладок, который является клоном этой базовой вкладки. заблокировать плагин. Я пытаюсь добавить возможность выбора «значка» для каждого блока вкладок.

Я близко. Используя компонент MediaUpload, я могу увидеть файл, который я выбрал в объекте activeTab, но он не обновляет атрибут родительского блока, поэтому я не могу ссылаться на атрибут icon_url .

Вкладка/edit.js

const Edit = ({ attributes, setAttributes, clientId }) => {
    const { uid, activeTab } = attributes;

    useEffect(() => {
        if (!uid) {
            setAttributes({ uid: clientId });
        }
    }, []);

    const display = activeTab === uid ? "block" : "none";
    const ALLOWED_MEDIA_TYPES = ["image", "svg"];

    const setTabIcon = (icon_url) => {
        const parentBlock = select("core/block-editor").getBlock(clientId);
        dispatch("core/block-editor").updateBlockAttributes(
            parentBlock.clientId,
            {
                ...attributes,
                icon_url,
            }
        );
    };

    return (
        <div {...useBlockProps()}>
            <InspectorControls>
                <div>
                    <MediaUpload
                        allowedTypes={ALLOWED_MEDIA_TYPES}
                        onSelect={(media) => setTabIcon(media.url)}
                        render={({ open }) => (
                            <button onClick={open}>Open Media Library</button>
                        )}
                    />
                </div>
            </InspectorControls>
            <div className={"guten-tab-panel"} style={{ display }}>
                <InnerBlocks
                    allowedBlocks={["core/heading", "core/paragraph"]}
                    renderAppender={() => <InnerBlocks.ButtonBlockAppender />}
                />
            </div>
        </div>
    );
};

export default Edit;

Я бы сначала подумал, что использование setAttributes здесь также обновит родительский элемент, но это только обновляет setActive в дочернем блоке. Это не сохраняет изменения.

В tabs.js я пытаюсь сослаться на tab.icon_url. icon_url не существует, только uid и title

Вкладки / tabs.js

const Edit = ({ attributes, setAttributes, clientId }) => {
    const { tabs, activeTab } = attributes;

    const blockProps = useBlockProps({
        className: `${useBlockProps().className} guten-tab-wrapper`,
    });

    const setActiveTab = (uid) => {
        setAttributes({ activeTab: uid });
        const parentBlock = select("core/block-editor").getBlock(clientId);
        parentBlock.innerBlocks.forEach((innerBlock) => {
            dispatch("core/block-editor").updateBlockAttributes(
                innerBlock.clientId,
                {
                    activeTab: uid,
                }
            );
        });
    };

    const addNewTab = () => {
        const tab = createBlock("ahsan03/tab");
        const position = tabs.length;
        dispatch("core/block-editor").insertBlock(tab, position, clientId);
        setAttributes({
            tabs: [
                ...tabs,
                {
                    uid: tab.clientId,
                    title: `Tab ${tabs.length + 1}`,
                    icon_url: "",
                },
            ],
        });
        setActiveTab(tab.clientId);
    };

    const tabTitleChange = (newValue) => {
        setAttributes({
            tabs: [
                ...tabs.map((tab) => {
                    return tab.uid === activeTab
                        ? {
                                ...tab,
                                title: newValue,
                          }
                        : tab;
                }),
            ],
        });
    };

    useEffect(() => {
        if (tabs.length && !activeTab) {
            setActiveTab(tabs[0].uid);
        }
    }, [tabs]);

    return (
        <>
            <div {...blockProps}>
                <div className={"guten-tabs-nav"}>
                    {tabs.map((tab) => {
                        return (
                            <div
                                key={tab.uid}
                                className={"guten-tab-item"}
                                role="tab"
                                tabIndex="0"
                                onClick={() => setActiveTab(tab.uid)}
                            >
                                <div
                                    className={`guten-tab-link${
                                        tab.uid === activeTab
                                            ? " is-active"
                                            : ""
                                    }`}
                                >
                                    <img src={tab.icon_url} alt="" />
                                    {console.log("tabs tab", {
                                        tab,
                                    })}
                                    <RichText
                                        tagName="div"
                                        value={tab.title}
                                        onChange={tabTitleChange}
                                    />
                                </div>
                            </div>
                        );
                    })}
                    <Button
                        variant={"primary"}
                        icon={"plus"}
                        onClick={addNewTab}
                    >
                        {__("", "gtt")}
                    </Button>
                </div>
                <div className={"guten-tab-content"}>
                    <InnerBlocks
                        allowedBlocks={["ahsan03/tab"]}
                        renderAppender={false}
                    />
                </div>
            </div>
        </>
    );
};

export default Edit;

Как я могу это исправить, чтобы загрузка изображения была в атрибутах родительского блока?

Вот обновленная функция setTabIcon, которая, как мне кажется, ближе к тому, что мне нужно, я просто не уверен, что делать после извлечения parentBlock.

const setTabIcon = (icon_url) => {
    const parentBlockIds =
        select("core/block-editor").getBlockParents(clientId);

    parentBlockIds.forEach((parentBlockId) => {
        const parentBlock = select("core/block-editor").getBlock(parentBlockId);
        console.log({ parentBlock });
    });
};
0
user15396919 27 Ноя 2022 в 08:30

2 ответа

Создайте переменную состояния в родительском компоненте, а затем передайте это состояние и setState дочернему в качестве реквизита, а затем из дочернего компонента вы можете обновить состояние в родительском компоненте.

0
Aneeq Khurram 27 Ноя 2022 в 08:44

Я смог исправить это, переместив setTabIcon и компонент MediaFile в родительский блок.

Буду рад предложениям по улучшению этого кода.

0
user15396919 27 Ноя 2022 в 09:04