如何使用 Semantic UI React 和 hooks 获取下拉列表的值

How to get value of dropdown using Semantic UI React, with hooks

我正在开发一个表格,其中连续有 3 个下拉菜单,最后一个下拉菜单可以有多个值。此外,还有一个添加或删除行的选项。当用户添加一行时,会出现一个包含三个下拉列表的新行。

我已经使用 React、React Semantic UI、Hooks、Typescript 来实现它。

现在,我试图在提交表单时从下拉列表中获取所选项目的值。但是,不确定我缺少什么来实现这一目标。当我添加一行时,新行将采用顶行的选定项目。

Image of my UI

我的代码是这样的:

import { Formik } from "formik";
import React, { Fragment } from "react";
import { useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { setModalStates } from "redux/actions/appActions";
import { IStore } from "redux/interfaces/types";
import { Button, Dropdown, Form, Grid, Icon } from "semantic-ui-react";

const QueryBuilder = () => {

    const [rulesetList, setrulesetList] = useState([{ entity: "", condition: "", val: "" }]);
    const mainField = [
        {
            key: "fruit",
            text: "fruit",
            value: "fruit"
        },
        {
            key: "color",
            text: "color",
            value: "color"
        },
        {
            key: "taste",
            text: "taste",
            value: "taste"
        }
    ]

    const operation = [
        {
            key: "is ",
            text: "is ",
            value: "is "
        },
        {
            key: "is not ",
            text: "is not ",
            value: "is not "
        }
    ]
    const options = [
        {
            key: "apple",
            text: "apple",
            value: "apple"
        },
        {
            key: "yellow",
            text: "yellow",
            value: "yellow"
        },
        {
            key: "sweet",
            text: "sweet",
            value: "sweet"
        },
    ]

    const [dropDownOptions, setDropDownOptions] = useState(options);
    const [currentValue, setCurrentValue] = useState("");
    const handleAddition = (e: any, { value }: any) => {
        setDropDownOptions((prevOptions) => [
            ...prevOptions,
            { key: value, text: value, value },
        ]);
    };

    const handleChange = (e: any, { value }: any) => {
        setCurrentValue(value);
    }

    const handleRemoveClick = (index: number) => {
        const list = [...rulesetList];
        list.splice(index, 1);
        setrulesetList(list);

    };

    const handleAddClick = () => {
        setrulesetList([...rulesetList, { entity: "", condition: "", val: "" }]);
        setDropDownOptions(options)
    };

    const initialValues = {
        mainField : "",
        operation: "",
        resultant_value: ""
    }

    return (
        <Fragment>
            {rulesetList.map((x, i) => {
                return (
                    <Grid >
                        <Grid.Row className={"rulesetGrid fluid"} >
                            <Formik
                                initialValues={initialValues}
                                onSubmit={values => {
                                    console.log("here",values)
                                }}

                            >
                                {
                                    ({ handleSubmit, values, setValues }) => (
                                        <Form onSubmit={handleSubmit} className={"rulesetForm"}>
                                            {i == 0 ? <p className="condition"> If</p> : <p className="condition"> And</p>}

                                            <Dropdown
                                                name="mainField"
                                                className={"dropdown fieldDropdown"}
                                                widths={2}
                                                placeholder='Fruit'
                                                fluid
                                                selection
                                                options={mainField}
                                            />

                                            <Dropdown
                                                name="operation"
                                                className={"dropdown operationDropdown"}
                                                widths={2}
                                                placeholder='Operation'
                                                fluid
                                                selection
                                                options={operation}
                                            />
                                            <Dropdown
                                                name="resultant_value"
                                                className={"dropdown valueDropdown"}
                                                widths={1}
                                                placeholder='Value'
                                                fluid
                                                search
                                                allowAdditions
                                                selection
                                                multiple
                                                options={dropDownOptions}
                                                value={currentValue }
                                                onAddItem={handleAddition}
                                                onChange={handleChange}
                                            />

                                            {rulesetList.length - 1 === i && <Icon className={"Plus plusIcon"} onClick={handleAddClick} />}
                                            {rulesetList.length !== 1 && <Icon className={"LineThicknessMedium signal-danger crossIcon"} onClick={() => handleRemoveClick(i)} />}
                                        </Form>
                                    )
                                }
                            </Formik>
                        </Grid.Row>

                    </Grid>
                );
            }
            )}
            <div>
                <div style={{ marginTop: "1rem" }}>
                    <Button
                        floated="right"
                        type="submit"
                        variant="contained"
                        primary={true}
                    >
                        Submit
                    </Button>
                </div>
            </div>
        </Fragment>
    );

}
export default QueryBuilder

您的代码中几乎没有什么需要更改的。

  1. 使用 Formik 时,无需显式维护状态来保存表单值。 Formik 会处理的。

  2. 您只是在更改值,而不是通知 formik 更改其状态。

  3. 由于您正在渲染 Fields 数组,您可以使用 Formik FieldArray 组件,它带有一堆助手,比如推送新行、删除行和更新每行中字段的值。

  4. 您的提交无效,因为您的提交按钮位于 <Formik /> 组件之外。所以点击 submit 按钮不会调用 FormikonSubmit .

已重构您的代码以使用 FieldArray。

Working codesandbox