0

I'm setting up an sidebar that include controls for some custom meta fields. I've got a parent functional component that include some inner child components, and I'd like to toggle (show/hide) different controls based on the selection of a RadioControl.

Here's what I got by now:

Parent component:

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

Child item (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);

This is working (meaning that the set/dispatch HOC allow to select and update the meta field values). What I'd like to obtain now is to pass the value of the MyRadioControl component to the parent component in order to toggle (hide/show) the respective control by means of a conditional statement (e.g. when "show-custom-1" value is selected in MyRadioControl, then show the MyCustom1 component etc...)

Maybe I got lost in a glass of water...

1 Answer 1

0

...as I said I was lost in a glass of water. Here's how I solved the problem in the situation described above (maybe it could help to newby React guys like me, but maybe some experts could provide a better solution):

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);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.