如何使用React选择依赖项中的Select组件的Menuisopen Prop有条件地显示按钮?

发布于 2025-02-12 18:24:23 字数 7083 浏览 1 评论 0原文

我在项目中使用某些组件进行下拉菜单。仅在打开下拉列表时,我才需要显示一个按钮。但是我无法弄清楚如何使用菜单prop来切换按钮渲染。有人从事这个工作还是可以在这里引导我?

这是我的自定义下拉列表:

import React, {useState} from "react";
import ReactSelect from "../../../../components/ReactSelect/ReactSelect";

const NewDropdown=props=>{
    const { state, component, onChange, selectWithoutBox} = props;
    const {optionList}=component;
    const [
        btnClick,
        setbtnClick
    ]=useState(false);
    
    const [
        inputValue,
        setInputValue
    ]=useState("");
    const [
        newList,
        setNewList
    ]=useState(optionList);

    const handleBtnClick=()=>{
        setbtnClick(true);
    };
    const handleInputChange=event=>{
        setInputValue(event.target.value);
    };

    const handleKeyPress=event=>{
        if(event.key==="Enter"){
            setNewList([
                ...newList,
                {label: inputValue, value: inputValue}
            ]);
            setbtnClick(false);
            setInputValue("");
        }
    };
    component.optionList=newList;

    
    return(
        <>
            <ReactSelect component={component} state={state} onChange={onChange} 
                
                selectWithoutBox={selectWithoutBox} />
            <div >
                { !btnClick && <button className="btn btn-icon" onClick={handleBtnClick}>ADD TYPE</button>}
                { btnClick && <input className="clr-input" type="text" placeholder="Enter Type" onChange={handleInputChange} value={inputValue} 
                    onKeyPress={handleKeyPress} autoFocus
                />}
            </div>
        </>
    );

};

export default NewDropdown;

这是我的ReactSelect组件 -

import React from "react";
import PropTypes from "prop-types";
import Select from "react-select";
import { get, isEmpty } from "../../helpers";
import BasicLabel from "../BasicLabel";
import "./ReactSelect.css";
import CheckboxOption from "./CheckboxOption/index";
import ShowOtherCountLimitContainer from "./ShowOtherCountLimitContainer";
import cn from "classnames";

const ReactSelect = props => {
    const customStyles = {
        option: provided => ({
            ...provided,
            container: "black",
            wordBreak: "break-all",
            input: "black",
            option: "black",
            color: "#565656",
            zIndex: 100000
        }),
        indicatorSeparator: styles => ({
            ...styles,
            "background-color" : "#FFFFFF"
        }),
        control: (styles, state) => ({
            ...styles,
            padding: 0,
            background: "#ffffff",
            border: ".05rem solid",
            "border-color": "#ccc",
            "border-radius": ".15rem",
            "min-height": "2rem",
            "min-width": "6rem",
            "background-color": state.isDisabled ? "#f2f2f2" : "#ffffff"
        }),
        menuPortal: styles => ({
            ...styles,
            zIndex: "9999"
        }),
        menu: styles => ({
            ...styles,
            marginTop:0
        }),
        container: styles => ({
            ...styles
        })
    };
    const customTheme = theme => ({
        ...theme,
        colors: {
            ...theme.colors,
            primary25:   "#D9E4EA",
            primary:   "#D9E4EA"
        }
    });
    const { state, component, onChange, disabled = false, selectWithoutBox, menuIsOpen} = props;
    let showError = false;
    const {
        name,
        required,
        label,
        helpTextPosition,
        helpText,
        placeholder,
        optionConfig = false,
        optionList = [],
        className,
        isMulti,
        maxItems = null,
        clearable = false,
        menuPlacement = "auto",
        maxMenuHeight = 300,
        dropdownCheckbox = false,
        showOtherCountLimit = -1
    } = component;

    const options = !!optionConfig ? get(state, `${optionConfig}`, []) : optionList;

    const getSelectValue = () => {
        const selectedList = get(state, `${name}`, []);
        if (isEmpty(selectedList) || isEmpty(options)) {
            return [];
        }
        const selectedSet = new Set(selectedList);
        return options.filter(item => selectedSet.has(item.value));
    };

    const handleOnChange = selectedOption => {
        onChange({ value: selectedOption, component });
    };

    if(isMulti && maxItems && getSelectValue().length > maxItems) {
        showError = true;
    }

    const selectStyleWithoutBox = {
        control: styles => ({
            ...styles,
            borderStyle:"none",
            borderBottomStyle:"solid",
            borderRadius:"0",
            boxShadow: "none"
        })
    };
    const styles = selectWithoutBox ? {...customStyles, ...selectStyleWithoutBox} : customStyles;

    const defaultSelectProps = {
        value: getSelectValue(),
        name: "category",
        className: "multiSelectTechspecs single-select",
        onChange: handleOnChange,
        isMulti,
        options,
        styles,
        theme: customTheme,
        menuPosition: "absolute",
        isDisabled: disabled,
        placeholder,
        isClearable: clearable,
        menuPlacement,
        maxMenuHeight,
        showOtherCountLimit, 
        menuIsOpen
    };

    /* ShowOtherCountLimitContainer will only be passed in ValueContainer if it has a valid value. ie. greater than 0 */

    const updatedComponents = showOtherCountLimit > 0 ? {
        Option: CheckboxOption,
        ValueContainer: ShowOtherCountLimitContainer
    } : { Option: CheckboxOption };

    const addonProps = dropdownCheckbox ? {
        components: updatedComponents,
        closeMenuOnSelect: false,
        hideSelectedOptions: false
    } : {};

    const classNames = cn("clr-form-control", "rs-wrapper", {"clr-error": showError});
    return (
        <div className={ classNames } key={name}>
            {label && <BasicLabel label = {label} required = {required}
                helpTextPosition = {helpTextPosition} helpText = {helpText}  />}
            <div className={`react-select-box ${className}`}>
                <Select
                    {...defaultSelectProps}
                    {...addonProps}
                    // menuIsOpen={menuIsOpen}
                />
                {
                    showError &&
                    <span className="clr-subtext multiselect-error">
                        You can select upto {maxItems} items only.
                    </span>
                }
            </div>

        </div>

    );
};

ReactSelect.propTypes = {
    selectWithoutBox: PropTypes.bool
};

ReactSelect.defaultProps = {
    selectWithoutBox: false
};
export default ReactSelect;

在这里,getiSempty方法是辅助功能。 get方法从任何对象或数组中获取所需值,如果该值未定义,则在此分配一个默认值。 ISEMPTY方法检查传递的值是否为空数组/对象。

I am using Select component in my project for dropdowns. I need to display a button only when the dropdown list is open. But I am not able to figure out how will I use the MenuIsOpen prop to toggle the button rendering. Anyone who has worked on this or can guide me here?

Here is my custom dropdown:

import React, {useState} from "react";
import ReactSelect from "../../../../components/ReactSelect/ReactSelect";

const NewDropdown=props=>{
    const { state, component, onChange, selectWithoutBox} = props;
    const {optionList}=component;
    const [
        btnClick,
        setbtnClick
    ]=useState(false);
    
    const [
        inputValue,
        setInputValue
    ]=useState("");
    const [
        newList,
        setNewList
    ]=useState(optionList);

    const handleBtnClick=()=>{
        setbtnClick(true);
    };
    const handleInputChange=event=>{
        setInputValue(event.target.value);
    };

    const handleKeyPress=event=>{
        if(event.key==="Enter"){
            setNewList([
                ...newList,
                {label: inputValue, value: inputValue}
            ]);
            setbtnClick(false);
            setInputValue("");
        }
    };
    component.optionList=newList;

    
    return(
        <>
            <ReactSelect component={component} state={state} onChange={onChange} 
                
                selectWithoutBox={selectWithoutBox} />
            <div >
                { !btnClick && <button className="btn btn-icon" onClick={handleBtnClick}>ADD TYPE</button>}
                { btnClick && <input className="clr-input" type="text" placeholder="Enter Type" onChange={handleInputChange} value={inputValue} 
                    onKeyPress={handleKeyPress} autoFocus
                />}
            </div>
        </>
    );

};

export default NewDropdown;

Here is my ReactSelect component-

import React from "react";
import PropTypes from "prop-types";
import Select from "react-select";
import { get, isEmpty } from "../../helpers";
import BasicLabel from "../BasicLabel";
import "./ReactSelect.css";
import CheckboxOption from "./CheckboxOption/index";
import ShowOtherCountLimitContainer from "./ShowOtherCountLimitContainer";
import cn from "classnames";

const ReactSelect = props => {
    const customStyles = {
        option: provided => ({
            ...provided,
            container: "black",
            wordBreak: "break-all",
            input: "black",
            option: "black",
            color: "#565656",
            zIndex: 100000
        }),
        indicatorSeparator: styles => ({
            ...styles,
            "background-color" : "#FFFFFF"
        }),
        control: (styles, state) => ({
            ...styles,
            padding: 0,
            background: "#ffffff",
            border: ".05rem solid",
            "border-color": "#ccc",
            "border-radius": ".15rem",
            "min-height": "2rem",
            "min-width": "6rem",
            "background-color": state.isDisabled ? "#f2f2f2" : "#ffffff"
        }),
        menuPortal: styles => ({
            ...styles,
            zIndex: "9999"
        }),
        menu: styles => ({
            ...styles,
            marginTop:0
        }),
        container: styles => ({
            ...styles
        })
    };
    const customTheme = theme => ({
        ...theme,
        colors: {
            ...theme.colors,
            primary25:   "#D9E4EA",
            primary:   "#D9E4EA"
        }
    });
    const { state, component, onChange, disabled = false, selectWithoutBox, menuIsOpen} = props;
    let showError = false;
    const {
        name,
        required,
        label,
        helpTextPosition,
        helpText,
        placeholder,
        optionConfig = false,
        optionList = [],
        className,
        isMulti,
        maxItems = null,
        clearable = false,
        menuPlacement = "auto",
        maxMenuHeight = 300,
        dropdownCheckbox = false,
        showOtherCountLimit = -1
    } = component;

    const options = !!optionConfig ? get(state, `${optionConfig}`, []) : optionList;

    const getSelectValue = () => {
        const selectedList = get(state, `${name}`, []);
        if (isEmpty(selectedList) || isEmpty(options)) {
            return [];
        }
        const selectedSet = new Set(selectedList);
        return options.filter(item => selectedSet.has(item.value));
    };

    const handleOnChange = selectedOption => {
        onChange({ value: selectedOption, component });
    };

    if(isMulti && maxItems && getSelectValue().length > maxItems) {
        showError = true;
    }

    const selectStyleWithoutBox = {
        control: styles => ({
            ...styles,
            borderStyle:"none",
            borderBottomStyle:"solid",
            borderRadius:"0",
            boxShadow: "none"
        })
    };
    const styles = selectWithoutBox ? {...customStyles, ...selectStyleWithoutBox} : customStyles;

    const defaultSelectProps = {
        value: getSelectValue(),
        name: "category",
        className: "multiSelectTechspecs single-select",
        onChange: handleOnChange,
        isMulti,
        options,
        styles,
        theme: customTheme,
        menuPosition: "absolute",
        isDisabled: disabled,
        placeholder,
        isClearable: clearable,
        menuPlacement,
        maxMenuHeight,
        showOtherCountLimit, 
        menuIsOpen
    };

    /* ShowOtherCountLimitContainer will only be passed in ValueContainer if it has a valid value. ie. greater than 0 */

    const updatedComponents = showOtherCountLimit > 0 ? {
        Option: CheckboxOption,
        ValueContainer: ShowOtherCountLimitContainer
    } : { Option: CheckboxOption };

    const addonProps = dropdownCheckbox ? {
        components: updatedComponents,
        closeMenuOnSelect: false,
        hideSelectedOptions: false
    } : {};

    const classNames = cn("clr-form-control", "rs-wrapper", {"clr-error": showError});
    return (
        <div className={ classNames } key={name}>
            {label && <BasicLabel label = {label} required = {required}
                helpTextPosition = {helpTextPosition} helpText = {helpText}  />}
            <div className={`react-select-box ${className}`}>
                <Select
                    {...defaultSelectProps}
                    {...addonProps}
                    // menuIsOpen={menuIsOpen}
                />
                {
                    showError &&
                    <span className="clr-subtext multiselect-error">
                        You can select upto {maxItems} items only.
                    </span>
                }
            </div>

        </div>

    );
};

ReactSelect.propTypes = {
    selectWithoutBox: PropTypes.bool
};

ReactSelect.defaultProps = {
    selectWithoutBox: false
};
export default ReactSelect;

Here, the get and IsEmpty methods are helper functions. get method gets the required value from any object or array and if the value is undefined, it assigns a default value there.
IsEmpty method checks whether passed value is empty array/object.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

月下伊人醉 2025-02-19 18:24:23

您可以使用onmenuopenonmenuclose props中的props props props
创建一个带有布尔值的状态,然后根据菜单打开和菜单关闭

https://reaect-select.com /道具

一个简单的演示
https://codesandbox.io/codesandbox.io/s/selastobox.io/selastic-jepsen -7epx7u?file =/src/app.js

You can use onMenuOpen and onMenuClose props in react select component
Create a state with boolean value and toggle the value based on menu open and menu close

https://react-select.com/props

A simple demo
https://codesandbox.io/s/elastic-jepsen-7epx7u?file=/src/App.js

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文