在 Wordpress Gutenberg Sidebar 中将状态从子组件传递到父组件

时间:2021-01-31 14:31:59

标签: reactjs wordpress wordpress-gutenberg react-sidebar

我正在设置一个侧边栏,其中包含一些自定义元字段的控件。我有一个包含一些内部子组件的父功能组件,我想根据 RadioControl 的选择来切换(显示/隐藏)不同的控件。

这是我现在得到的:

父组件:

import { __ } from "@wordpress/i18n";
import {
    PanelBody,
    PanelRow,
    HorizontalRule
} from "@wordpress/components";

/**
 * Local dependencies.
 */
import icons from './icons.js'

import MyRadioControl from "./my-radio-control";
import MyCustom1 from "./my-custom-1";
import MyCustom2 from "./my-custom-2";
import MyCustom3 from "./my-custom-3";

const ParentItem = () => {

    return (
        <PanelBody
            title={__("Parent item", "textdomain")}
            icon={icons.parentItem}
            initialOpen={false}
        >
            <PanelRow>
                <MyRadioControl />
            </PanelRow>
            <HorizontalRule />
            <PanelRow>
                <MyCustom1 />
            </PanelRow>
            <HorizontalRule />
            <PanelRow>
                <MyCustom2 />
            </PanelRow>
            <HorizontalRule />
            <PanelRow>
                <MyCustom3 />
            </PanelRow>
        </PanelBody>
    )
}

export default ParentItem

子项(RadioControl):

import { __ } from "@wordpress/i18n";
import { compose } from "@wordpress/compose";
import { withSelect, withDispatch } from "@wordpress/data";
import { RadioControl } from "@wordpress/components";

const MyRadioControl = ({ metaFieldValue, setMetaFieldValue }) => {
    return (
        <RadioControl
            label={__("MyRadioControl", "textdomain")}
            selected={
                metaFieldValue ? metaFieldValue : "none"
            }
            options={[
                {
                    label: __("None", "textdomain"),
                    value: 'none'
                },
                {
                    label: __("Show custom 1", "textdomain"),
                    value: 'show-custom-1'
                },
                {
                    label: __("Show custom 2", "textdomain"),
                    value: 'show-custom-2'
                },
                {
                    label: __("Show custom 3", "textdomain"),
                    value: 'show-custom-3'
                },
            ]}
            onChange={setMetaFieldValue}
        />
    )
}

export default compose([
    withDispatch((dispatch, props) => {
        return {
            setMetaFieldValue: function (value) {
                dispatch('core/editor').editPost({ meta: { _mysite_my_radio_control: value } });
            }
        }
    }),
    withSelect((select, props) => {
        return {
            metaFieldValue: select('core/editor').getEditedPostAttribute('meta')['_mysite_my_radio_control'],
        };
    }),
])(MyRadioControl);

这是有效的(意味着设置/调度 HOC 允许选择和更新元字段值)。我现在想获得的是将 MyRadioControl 组件的值传递给父组件,以便通过条件语句(例如,当“show-custom-1”值时)切换(隐藏/显示)相应的控件在 MyRadioControl 中选择,然后显示 MyCustom1 组件等...)

也许我在一杯水里迷路了...

1 个答案:

答案 0 :(得分:0)

...正如我所说,我迷失在一杯水中。以下是我在上述情况下解决问题的方法(也许它可以帮助像我这样的 React 新手):

const ParentItem = ({ state, setState }) => {

    return (
        <PanelBody
            title={__("Parent item", "textdomain")}
            initialOpen={false}
        >
        <PanelRow>
            <RadioControl
                label={__("MyRadioControl", "textdomain")}
                selected={ state ? state : "none" }
                options={[
                    {
                        label: __("None", "textdomain"),
                        value: 'none'
                    },
                    {
                        label: __("Show custom 1", "textdomain"),
                        value: 'show-custom-1'
                    },
                    {
                        label: __("Show custom 2", "textdomain"),
                        value: 'show-custom-2'
                    },
                    {
                        label: __("Show custom 3", "textdomain"),
                        value: 'show-custom-3'
                    },
                ]}
                onChange={setState}
            />
        </PanelRow>

        {state === "show-custom-1" &&
            <PanelRow>
                <MyCustom1 />
            </PanelRow>
        }

        {state === "show-custom-2" &&
            <PanelRow>
                <MyCustom2 />
            </PanelRow>
        }

        {state === "show-custom-3" &&
            <PanelRow>
                <MyCustom3 />
            </PanelRow>
        }
    </PanelBody>
)}

export default compose([
    withDispatch((dispatch, props) => {
        return {
            setState: function (value) {
                dispatch('core/editor').editPost({ meta: { _mysite_my_radio_control: value } });
            }
        }
    }),
    withSelect((select, props) => {
        return {
            state: select('core/editor').getEditedPostAttribute('meta')['_mysite_my_radio_control'],
        };
    }),
])(ParentItem);