首页 > 解决方案 > 在按钮上渲染组件单击子级使用 forwardRef 调用组件的位置

问题描述

我目前正在学习 React,我有一个问题。

我已经构建了一个自定义的 PopUp 组件,如下所示:

import React, {forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState} from "react";
import PropTypes from "prop-types";
import Button from "../Button/Button";
import './PopUp.sass';

export function PopUp(props, ref) {

    const {handleCancel, handleSave, handleClose, children} = props;
    const popUpRef = useRef(null);
    const [isActive, setIsActive] = useState(false);

    const close = useCallback(() => setIsActive(false));

    useImperativeHandle(ref, () => ({
        open: () => setIsActive(true),
        close: close,
        isActive: isActive
    }), [close]);

    const handleEscape = useCallback(event => {
        if (event.keyCode === 27) close();
    }, [close]);

    useEffect(() => {
        if (isActive) document.addEventListener('keydown', handleEscape, false);
        return () => {
            document.removeEventListener('keydown', handleEscape, false);
        }
    }, [handleEscape, isActive]);

    return (
        <div className="PopUp-Container">
            <div className={`PopUp-Content ${isActive ? 'Active' : 'Inactive'}`} ref={popUpRef}>
                {
                    isActive && (
                        <div>
                            <header className="PopUp-Header PopUp-Container--Content">
                            <span
                                className="PopUp-Close Close-Icon"
                                aria-label="close"
                                onClick={close}>
                                X
                            </span>
                                <h2>Modal Header</h2>
                            </header>
                            <div className="PopUp-Container--Content">
                                {children}
                            </div>
                            <footer className="PopUp-Container--Content PopUp-Buttons">
                                <Button
                                    label="Save"
                                    handleClick={() => handleSave}
                                    className="Success"/>
                                <Button
                                    label="Cancel"
                                    handleClick={() => handleCancel}
                                    className="Info"/>
                            </footer>
                        </div>
                    )
                }
            </div>
        </div>
    );
}

PopUp.propTypes = {
    handleCancel: PropTypes.func,
    handleSave: PropTypes.func,
    handleClose: PropTypes.func,
    children: PropTypes.string
};

export default forwardRef(PopUp);

此外,我构建了一个包含 PopUp 的 PicklistPopUp。我这样做了,因为我不止一次需要这个组件。该组件如下所示:

import React, {useRef} from "react";
import PropTypes from 'prop-types';
import {PopUp} from "../../input/PopUp/PopUp";

const PicklistPopUp = (props) => {

    const {picklistValue} = props;
    const popUpRef = useRef(null);

    return (
        <PopUp
            ref={popUpRef}>
            <section className="Field-Section-Content">
                <span className="Label">Picklist Label</span>
                <span className="Data">{picklistValue.label}</span>
            </section>
        </PopUp>
    );

}

PicklistPopUp.propTypes = {
    picklistValue: PropTypes.object
};

export default PicklistPopUp;

最后,我有一个组件,我在其中呈现一个表格,并且用户有选项来编辑记录。因此,我想展示 PicklistPopUp 组件。但我不知道最好的方法,如何实现这一目标。我当前的表格组件看起来像这样(注意:我已经删除了一些对于这个问题不是必需的代码):

import React, {useEffect, useRef, useState} from "react";
import PropTypes from 'prop-types';
import Button from "../../../../../../input/Button/Button";
import PicklistPopUp from "../../../../../../ui/PopUps/PicklistPopUp";

const ObjectManagerFieldPicklist = (props) => {

    const {object, field} = props;
    let selectedPicklistValue = {};

    const handleEdit = (picklistValue) => {
        console.log(picklistValue);
        selectedPicklistValue = picklistValue;
        renderPicklistPopUp();
    }

    const renderPicklistPopUp = () => {
        return (
            <PicklistPopUp
                picklistValue={selectedPicklistValue}/>
        );
    }

    return (
        <div>
            {renderPicklistPopUp()}
            <Button
                label="Edit"
                handleClick={() => handleEdit(picklistValue)}/>
        </div>
    )

}

ObjectManagerFieldPicklist.propTypes = {
    object: PropTypes.string.isRequired,
    field: PropTypes.string.isRequired
};

export default ObjectManagerFieldPicklist;

我的目标是,用户可以单击编辑按钮并看到 PicklistPopUp,他可以在其中更改记录。

如果您有一些问题或需要更多源代码,请告诉我,我会更新问题。

标签: reactjs

解决方案


推荐阅读