首页 > 解决方案 > 在表单的钩子中使用对象

问题描述

我刚刚开始使用 REACT,并且正在寻找一种在使用具有许多控件的表单时的有效方法。而且我不需要任何验证,所以我跳过了 react-hook-forms。

使用表单时有什么推荐的做法吗?我有大约 20 个输入,所以它是一个半大型表格。我开始为每个输入设置一个钩子,但很快意识到它有点难以维护。所以我改为使用一个带有这样的对象的钩子:

https://codesandbox.io/s/bind-input-kzzd3

我可以看到有些人为表单推荐减速器,为了简单起见,将钩子与像我的示例这样的对象一起使用有什么问题吗?减速机会给我额外的什么?或者你会为每个输入选择一个钩子吗?

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

import { Row, Col, Form, FormGroup, Label, Input, Button } from "reactstrap";

export default function App() {
  const onSearch = val => {
    alert(val);
  };

  return (
    <div className="App">
      <GetSearchForm onSearch={onSearch} />
    </div>
  );
}

const GetSearchForm = props => {
  const [val, setVal] = useState();

  const [formData, setFormData] = useState({
    accountId: 0,
    firstName: "",
    lastName: ""
  });

  const onSearch = event => {
    event.preventDefault();
    props.onSearch(val);
  };

  return (
    <Form onSubmit={onSearch}>
      <Row>
        <Col>
          <FormGroup>
            <Label for="exampleEmail">Account Id</Label>
            <Input
              type="number"
              name="account"
              id="account"
              placeholder="AccountId"
              onChange={e =>
                setFormData({ ...formData, accountId: e.target.value })
              }
            />
          </FormGroup>
        </Col>
      </Row>
      <Row>
        <Col>
          <FormGroup>
            <Label for="firstName">Firstname</Label>
            <Input
              type="text"
              name="firstName"
              id="firstName"
              placeholder="Firstname"
              value={val}
              onChange={e => setVal(e.target.value)}
            />
          </FormGroup>
        </Col>
      </Row>
      <Row>
        <Col>
          <FormGroup>
            <Label for="exampleEmail">Lastname</Label>
            <Input
              type="text"
              name="lastName"
              id="lastName"
              placeholder="Lastname"
              value={val}
              onChange={e => setVal(e.target.value)}
            />
          </FormGroup>
        </Col>
      </Row>

      <Button>Submit</Button>

      <div>{JSON.stringify(formData, null, 2)}</div>
    </Form>
  );
};

标签: reactjs

解决方案


我不需要任何验证,所以我跳过了 react-hook-forms。

我假设您使用的钩子意味着 React.useState。是的,如果您不想使用其他表单库,那么以这种方式更新您的状态是完全可以的。更新状态时要小心useEffect,闭包有问题,状态没有正确更新。

使用表单时的任何推荐做法

如上所述,关闭时要小心,(状态未正确更新)我建议使用setState((prevState)=>return your modified state).

减速机会给我额外的什么?或者你会为每个输入选择一个钩子吗?

useReducer 对 setState 有更多控制权。

我有大约 20 个输入,所以它是一个半大型表格。

最好是使用表单库,而不是使每个状态成为独立的状态。我使用过formik,它不需要状态管理来使用,有或没有 yup 的预构建验证。(当您的表格增长时,在您的情况下> 20个输入)


推荐阅读