简体   繁体   English

根据状态变量反应更改输入元素

[英]React change Input elements based on state variable

I'm trying to change the Inputs that I display based on id state variable that the user can select in a dropdown.我正在尝试根据用户可以在下拉列表中选择的id状态变量更改我显示的输入。 It's odd, but after changing the select ID, the Inputs are rendered properly, but it is setting the previous Input value to the new Input.这很奇怪,但在更改select ID 后,输入正确呈现,但它将以前的输入值设置为新的输入。 Also, the submit is validating Input that does not exist.此外,提交正在验证不存在的输入。

import React, { useState, useEffect } from "react";
import { Controller, useForm } from "react-hook-form";
import { Button, Form, Label, Input } from "reactstrap";

const App = () => {
  const [id, setID] = useState(1);
  const units = [
    { UnitID: 1, UnitName: "101" },
    { UnitID: 2, UnitName: "102" },
    { UnitID: 3, UnitName: "103" },
    { UnitID: 4, UnitName: "104" }
  ];

  useEffect(() => {
    console.log("ID was updated");
  }, [id]);

  const {
    handleSubmit,
    control,
    setValue,
    formState: { errors }
  } = useForm();

  const handleChangeDeposit = (id) => {
    setValue("id", parseInt(id));
    setID(parseInt(id));
  };

  const resetFields = () => {
    setValue("transactionComment", "");
    setValue("unitID", 0);
  };

  const renderTest = () => {
    switch (parseInt(id)) {
      case id === 3 || id === 5:
        resetFields();
        return (
          <div className="col-sm-3">
            <Label for="transactionComment" className="mr-sm-10">
              Comment
            </Label>
            <Controller
              name="transactionComment"
              control={control}
              rules={{ required: true }}
              defaultValue={""}
              render={({ field }) => (
                <Input {...field} type="text" id="transactionComment" />
              )}
            />
            {errors.transactionComment && (
              <span style={{ color: "red" }} role="alert">
                required
              </span>
            )}
          </div>
        );
      case 11:
        resetFields();
        setValue("transactionComment", "Laundry Room");
        return (
          <div className="col-sm-3">
            <Label for="transactionComment" className="mr-sm-10">
              Comment
            </Label>
            <Controller
              name="transactionComment"
              control={control}
              defaultValue={"Laundry Room"}
              render={({ field }) => (
                <Input
                  {...field}
                  type="text"
                  id="transactionComment"
                  readOnly
                />
              )}
            />
          </div>
        );
      default:
        resetFields();
        return (
          <div className="col-sm-3">
            <Label for="unitID" className="mr-sm-10">
              Unit
            </Label>
            <Controller
              name="unitID"
              control={control}
              rules={{ required: true }}
              defaultValue={0}
              render={({ field }) => (
                <Input {...field} type="select" id="unitID">
                  <option value="0">Select</option>
                  {units.map((obj) => {
                    return (
                      <option key={obj.UnitID} value={obj.UnitID}>
                        {obj.UnitName}
                      </option>
                    );
                  })}
                </Input>
              )}
            />
            {errors.unitID && (
              <span style={{ color: "red" }} role="alert">
                required
              </span>
            )}
          </div>
        );
    }
  };

  const submitForm = (data) => {
    if ([3, 5].includes(id) && data.transactionComment === "") {
      alert("Transaction Comment is require");
      return;
    }
    if (![3, 5].includes(id) && parseInt(data.unitID) === 0) {
      alert("Unit is required.");
      return;
    }
    alert("Updated!");
  };

  return (
    <div className="row">
      <div className="col-sm-12 col-md-12 col-xl-12">
        <Form onSubmit={handleSubmit(submitForm)}>
          <div className="row">
            <div className="col-sm-3">
              <Label for="id" className="mr-sm-10">
                Select
              </Label>
              <Controller
                name="id"
                control={control}
                rules={{ required: true }}
                defaultValue={1}
                render={({ field }) => (
                  <Input
                    {...field}
                    type="select"
                    id="id"
                    onChange={(e) => handleChangeDeposit(e.target.value)}
                  >
                    <option value="0">Select</option>
                    <option value="3">Option 3</option>
                    <option value="5">Option 5</option>
                    <option value="11">Option 11</option>
                    <option value="15">Others</option>
                  </Input>
                )}
              />
              {errors.id && (
                <span style={{ color: "red" }} role="alert">
                  required
                </span>
              )}
            </div>
            {renderTest()}
            <div className="col-sm-3">
              <Label for="memo" className="mr-sm-10">
                Memo
              </Label>
              <Controller
                name="memo"
                control={control}
                render={({ field }) => (
                  <Input
                    {...field}
                    type="text"
                    name="memo"
                    placeholder="12345"
                  />
                )}
              />
            </div>
          </div>
          <Button type="submit">Update</Button>
        </Form>
      </div>
    </div>
  );
};

export default App;

Here is the SandBox: https://codesandbox.io/s/serene-greider-z3xpd?file=/src/App.js:0-5426这是沙盒: https ://codesandbox.io/s/serene-greider-z3xpd ? file =/ src/App.js:0-5426

Thanks谢谢

Issue问题

The issue is in your renderTest function, you've a malformed switch case.问题出在您的renderTest函数中,您的开关盒格式错误。

const renderTest = () => {
  switch (parseInt(id)) {
    case id === 3 || id === 5:
      ...

    case 11:
      ...

    default:
      ...
  }
};

id === 3 || id === 5 id === 3 || id === 5 resolves to a boolean but you are switching on id which is one of the values 0 , 3 , 5 , 11 , and 15 . id === 3 || id === 5解析为布尔值,但您正在打开id ,它是值0351115 Since none of the id values is true/false the default case is rendered.由于所有id值都不是 true/false,因此会呈现默认情况。

When submitForm is invoked the "comment" validation is checked.当调用submitForm检查“评论”验证。

if ([3, 5].includes(id) && data.transactionComment === "") {
  alert("Transaction Comment is require");
  return;
}

Solution解决方案

Fix the switch statement to use two distinct cases for id 3 and 5.修复 switch 语句以对 id 3 和 5 使用两种不同的情况。

const renderTest = () => {
  switch (parseInt(id)) {
    case 3:
    case 5:
      ...

    case 11:
      ...

    default:
      ...
  }
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM