我正在try 创建一些东西,用户可以添加多个地址,最多3个,默认的一个不能删除.

在本例中,地址只是街道名称和城市.

我正在努力弄清楚如何处理这个场景中的状态和表单输入字段.

我可以 for each 地址设置3个不同的州,并以这种方式以州的值为目标,但我想知道你们是否有更干净的方法来做这样的事情.

提交表单后,我需要这些地址的数组,因为它们在我的用例中构成另一个对象的一部分.

以下是react 代码

import { useState } from "react";
import "./styles.css";

export default function App() {
  const [addressCount, setAddressCount] = useState(1);
  const [address, setAddress] = useState([]);

  const handleAddressChange = (event) => {
    const { name, value } = event.target;
    // handle address state
  };

  const addAddress = () => {
    if (addressCount == 3) {
      alert("you cannot more than 3 addresses");
      return;
    }
    setAddressCount(addressCount + 1);
  };

  const removeAddress = () => {
    if (addressCount == 1) {
      alert("You cannot remove this address");
      return;
    }
    setAddressCount(addressCount - 1);
  };

  const AddressDiv = (index) => {
    return (
      <div key={index} className="address-section">
        <div className="mb-2">
          <label>Street name</label>
          <input
            type="text"
            placeholder="Enter street name"
            name="streetName"
            onChange={handleAddressChange}
          />
        </div>
        <div className="mb-2">
          <label>City</label>
          <input
            type="text"
            placeholder="Enter city name"
            name="streetName"
            onChange={handleAddressChange}
          />
        </div>
        <div className="add-another-address-section mt-3 mb-4">
          <button type="button" onClick={addAddress}>
            + Add another
          </button>
          <button type="button" onClick={removeAddress}>
            - Remove
          </button>
        </div>
      </div>
    );
  };

  return (
    <div className="App">
      DIV COUNT {addressCount}
      <AddressDiv />
      {Array.from({ length: addressCount - 1 }, (_, index) => {
        return <div style={{ margin: "2rem" }}>{AddressDiv(index)}</div>;
      })}
    </div>
  );
}

这是一个CodeSandbox链接,显示了它的大致外观.

https://codesandbox.io/p/sandbox/generate-div-8hknk3?file=%2Fsrc%2FApp.js%3A63%2C26

推荐答案

addressCount是冗余状态,应将其删除,因为它总是可以从address(即address.length)计算得出.代码可以简化如下:

export default function App() {
  const [address, setAddress] = useState([{ id: 0 }]);
  const id = useRef(0);
  const addAddress = (insertAfter) => {
    if (address.length === 3) alert('you cannot more than 3 addresses');
    else
      setAddress(address.toSpliced(insertAfter + 1, 0, { id: ++id.current }));
  };
  const removeAddress = (index) => {
    if (index === 0) alert('You cannot remove this address');
    else setAddress(address.toSpliced(index, 1));
  };
  const handleChange = (event, index) => {
    setAddress(
      address.map((o, i) =>
        i !== index ? o : { ...o, [event.target.name]: event.target.value }
      )
    );
  };
  return (
    <div className="App">
      DIV COUNT {address.length}
      {address.map((o, index) => (
        <div key={o.id} className="address-section">
          <div className="mb-2">
            <label>Street name</label>
            <input
              type="text"
              placeholder="Enter street name"
              name="streetName"
              value={o.streetName}
              onChange={(e) => handleChange(e, index)}
            />
          </div>
          <div className="mb-2">
            <label>City</label>
            <input
              type="text"
              placeholder="Enter city name"
              name="cityName"
              value={o.cityName}
              onChange={(e) => handleChange(e, index)}
            />
          </div>
          <div className="add-another-address-section mt-3 mb-4">
            <button type="button" onClick={() => addAddress(index)}>
              + Add another
            </button>
            <button type="button" onClick={() => removeAddress(index)}>
              - Remove
            </button>
          </div>
        </div>
      ))}
    </div>
  );
}

Javascript相关问答推荐

在JavaScript中对大型级联数组进行切片的最有效方法?

使用json文件字符串来enum显示类型字符串无法按照计算的enum成员值的要求分配给类型号

Plotly热图:在矩形上zoom 后将zoom 区域居中

在Angular中将样式应用于innerHTML

网页自检测外部元素无法加载

如何使覆盖div与可水平滚动的父div相关?

构造HTML表单以使用表单数据创建对象数组

WebGL 2.0无符号整数输入变量

Angular 订阅部分相互依赖并返回数组多个异步Http调用

React.Development.js和未捕获的ReferenceError:未定义useState

有效路径同时显示有效路径组件和不存在的路径组件

删除加载页面时不存在的元素(JavaScript)

如何使用<;Link>;执行与JS Reaction中的";window.Location=/GameOverDied;";类似的操作?

未捕获语法错误:Hello World中的令牌无效或意外

将Auth0用户对象存储在nextjs类型脚本的Reaction上下文中

JSON Web令牌(JWT)错误:RSA密钥对的签名无效

不允许在对象文本中注释掉的属性

使用Java脚本筛选数组中最接近值最小的所有项

如何动态呈现适合未知屏幕大小的最大数量的表行?苗条的

JavaScript structuredClone在Chrome/Edge中获得了非法调用,但在NodeJS中没有