javascript 组件函数重新呈现onChange

gojuced7  于 2023-03-11  发布在  Java
关注(0)|答案(1)|浏览(118)

我有一个react应用程序。这个特定的组件有许多不同的表单。因此,我创建了外部函数,当我想显示一个特定的表单时,我会调用这些组件函数。
示例:

const Create = () => {
    const [formValid, setFormValid] = useState(true);

    const [noBoats, setNoBoats] = useState();
    const [noHouses, setNoHouses] = useState();

    const [isForm1, setIsForm1] = useState(true);

    const validateForm = ({ currentTarget: input }) => {
        if (input['name'] == 'no_boats') {
            setNoBoats(input.value)

            if (input.value != '') {
                if (between(input.value, 0, 4)) {
                    setFormValid(true)
                } else {
                    setFormValid(false)
                }
            }
        }

        if (input['name'] == 'no_houses') {
            setNoHouses(input.value)

            if (input.value != '') {
                if (between(input.value, 0, 8)) {
                    setFormValid(true)
                } else {
                    setFormValid(false)
                }
            }
        }
    }

    const Form1 = () => {
      return (
      <>

        <form className={styles.form} id="form1" onSubmit={(e) => handleSubmit(e)}>
          <div className={styles.form_group}>
            <label htmlFor="no_houses">Number of Houses</label>
            <input type="text" name="no_houses" autoFocus="autoFocus" onChange={validateForm} value={noHouses}/>
          </div>

          <div className={styles.form_group}>
            <label htmlFor="no_boats">Number of Boats</label>
            <input type="text" name="no_boats" autoFocus="autoFocus" onChange={validateForm} value={noBoats}/>
          </div>

          <button type="submit">Submit</button>
        </form>
        </>
      );
    }

    return (
            <div className={styles.all_forms}>
                  {isForm1 && <Form1 />}
            </div>

    );
}

当我填写“船数”和“房屋数”时,输入在第一个字符后失去了焦点。我试着将autoFocus="autoFocus"添加到这两个输入中,但也不起作用。请解释一下这是怎么回事?
我怀疑这可能与以下事实有关:我使用<Form />加载Form1组件,当状态更新时,它会重新呈现该表单。不幸的是,我有大约10个不同的表单,因此无法将它们全部放入主render()

pvcm50d1

pvcm50d11#

每当Create组件重新呈现时,Form1组件都会被重新声明,这(* 显然 *)是一个新的组件引用,并且会重新挂载该组件,这就是输入焦点丢失的原因。
声明Form1独立于任何其他React组件之外,这样它就是一个稳定的引用,你需要把所有的回调函数和值作为props传入。

const Form1 = ({
  formValid,
  handleChange,
  handleSubmit,
  noBoats,
  noHouses
}) => {
  return (
    <form
      className={styles.form}
      id="form1"
      onSubmit={handleSubmit}
    >
      <div className={styles.form_group}>
        <label htmlFor="no_houses">Number of Houses</label>
        <input
          type="text"
          name="no_houses"
          autoFocus="autoFocus"
          onChange={handleChange}
          value={noHouses}
        />
      </div>

      <div className={styles.form_group}>
        <label htmlFor="no_boats">Number of Boats</label>
        <input
          type="text"
          name="no_boats"
          autoFocus="autoFocus"
          onChange={handleChange}
          value={noBoats}
        />
      </div>

      <button disabled={!formValid} type="submit">Submit</button>
    </form>
  );
};
const Create = () => {
  const [formValid, setFormValid] = useState(true);

  const [noBoats, setNoBoats] = useState("");
  const [noHouses, setNoHouses] = useState("");

  const [isForm1, setIsForm1] = useState(true);

  useEffect(() => {
    let isValid = true;

    if (noBoats && !between(noBoats, 0, 4)) {
      isValid = false;
    }

    if (noHouses && !between(noHouses, 0, 8)) {
      isValid = false;
    }
    setFormValid(isValid);
  }, [noBoats, noHouses, setFormValid]);

  const handleChange = ({ currentTarget }) => {
    const { name, value } = currentTarget;

    if (input.name === 'no_boats') {
      setNoBoats(input.value);
    }

    if (input.name === 'no_houses') {
      setNoHouses(input.value);
    }
  }

  return (
    <div className={styles.all_forms}>
      {isForm1 && (
        <Form1 
          formValid={formValid}
          handleSubmit={handleSubmit}
          handleChange={handleChange}
          noBoats={noBoats}
          noHouses={noHouses}
        />
      )}
    </div>
  );
};

相关问题