Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
596 views
in Technique[技术] by (71.8m points)

javascript - Input field loses focus after typing one character in react app

In my case I have a dropdown and based on the number selected with the dropdown some input fields appear. When I type into the input field the focus on that input field is lost after typing one character. Setting a unique key for each field is not solving my problem.

Link to the project: https://codesandbox.io/s/stoic-brahmagupta-m5014


const ItemPrice = () => {
  const data = itemData.doReservation.eventPackage.item;

  let emptyCat = {};
  let emptyQnt = {};
  let promoNum = {};
  let emptyPromotion = {};

  const [promoNumber, setPromoNumber] = useState(promoNum);

  for (let it in data) {
    let cat = {};
    let promo = {};

    for (let bt in data[it].buyertypes) {
      cat[data[it].buyertypes[bt].id] = "";
      emptyQnt[data[it].buyertypes[bt].id] = 0;
      promo[data[it].buyertypes[bt].id] = "";
      promoNum[data[it].buyertypes[bt].id] = [];
      emptyPromotion[data[it].buyertypes[bt].id] = {};
    }
    emptyCat[data[it].id] = cat;
    cat = {};
  }

  const [quantity, setQuantity] = useState(emptyQnt);
  const [code, setCode] = useState(emptyPromotion);

  const handleQuantity = (e) => {
    const name = e.target.name;
    const value = e.target.value;
    setQuantity({
      ...quantity,
      [name]: value
    });
    let num = [];
    for (let i = 1; i <= value; i++) {
      num.push(i);
    }
    setPromoNumber({ ...promoNumber, [name]: num });
    let num2 = {};
    for (let pn = 1; pn <= value; pn++) {
      if (code[name]["code" + name + pn] === undefined) {
        num2["code" + name + pn] = "";
      } else {
        num2["code" + name + pn] = code[name]["code" + name + pn];
      }
    }
    setCode({ ...code, [name]: num2 });
  };

  const handleCode = (e) => {
    e.preventDefault();
    const sp = e.target.name.split(",");
    const id1 = sp[0];
    const id2 = sp[1];
    const value = e.target.value;
    setCode({
      ...code,
      [id1]: {
        ...code[id1],
        [id2]: value
      }
    });
  };

  const ShowData = () => {
    let buyerTypes = [];
    let items = [];
    if (data) {
      for (let it in data) {
        items.push(
          <div className="selectionHeader">
            <div className="selHeadType">type</div>
            <div className="selHeadQnt">Quantity</div>
            <div className="selHeadCat">Price category</div>
          </div>
        );
        for (let bt in data[it].buyertypes) {
          buyerTypes.push({
            dsc: data[it].buyertypes[bt].description,
            qntId: data[it].buyertypes[bt].id
          });
        }
        items.push(
          <div>
            {buyerTypes.map((i, index) => (
              <div key={`a${index}`} className="selectionRowComp">
                <div key={`c${index}`} className="selectionRow">
                  <h4 className="btDescription">{i.dsc}</h4>
                  <div className="NumberDropDown">
                    <select
                      value={quantity[i.qntId]}
                      onChange={handleQuantity}
                      name={i.qntId}
                    >
                      {[0, 1, 2, 3, 4, 5, 6].map((l) => {
                        return (
                          <option value={l} key={l}>
                            {l}
                          </option>
                        );
                      })}
                    </select>
                  </div>
                </div>
                <div>
                  {promoNumber[i.qntId].map((p, index) => (
                    <div key={`s${index}`}>
                      <label className="codeLabel">code {p}: </label>
                      <input
                        className="codeInput"
                        type="text"
                        value={code[i.qntId]["code" + i.qntId + (index + 1)]}
                        onChange={handleCode}
                        name={[i.qntId, "code" + i.qntId + (index + 1)]}
                        // required={hasPromotion[i.qntId]}
                      />
                    </div>
                  ))}
                </div>
              </div>
            ))}
          </div>
        );
        buyerTypes = [];
      }
    }
    return (
      <div className="selectionItem">
        {items.map((it, index) => {
          return <div key={`w${index}`}> {it}</div>;
        })}
      </div>
    );
  };

  const handleSubmit = (e) => {
    e.preventDefault();
  };

  return (
    <div>
      <div>
        <div>
          <form onSubmit={handleSubmit}>
            <ShowData />
          </form>
        </div>
      </div>
    </div>
  );
};

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You have to decouple Parent (ItemPrice) and Child (ShowData) components respectively.

A through re-factor of your code is needed. Because dependencies like const data is defined in ItemPrise and used in child component ShowData, rather it should be sent down as Props to ShowData component.

ShowData component should not be directly dependent on any variable/const defined in ItemPrise component. All such dependencies should be passed using any of the following basis your use-case and application requirements:

  1. Props
  2. Context
  3. Global state management such as Redux
  4. Custom Hook

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...