【问题标题】:Use the same form component for both, add and update. ReactJs对两者使用相同的表单组件,添加和更新。反应式
【发布时间】:2019-08-23 13:36:51
【问题描述】:

我正在处理事务表。我只想添加、删除和更新表中的事务。

我有一个“Transactions.js”功能组件,它具有交易状态(使用钩子),我还有一个“TransactionsForm.js”组件,它接收“setTransactions”函数作为来自“Transactions.js”的道具添加或更新交易状态

Transactions.js

const [transactions, setTransactions] = useReducer(
   transactionsReducer,
   fetchTransactions()
)

TransactionsForm.js

const [values, setValues] = useState({
    description: '',
    transactionType: '',
    date: '',
    category: '',
    amount: ''
  })

  const handleChange = event => {
    const { name, value } = event.target
    setValues({ ...values, [name]: value })
  }

  const handleAdd = () => {
    setTransactions({
      type: 'add',
      transactionType: 'income',
      description: values.description,
      date: values.date,
      category: values.category,
      amount: values.amount
    })
  }

  const handleUpdate = () => {
    setTransactions({
      type: 'update',
      id: 1,
      transactionType: 'income',
      description: values.description,
      date: values.date,
      category: values.category,
      amount: values.amount
    })
  }

  const handleSubmit = event => {
    event.preventDefault()
    // 1. handleUpdate()  if the user is updating an existing transaction
    // 2. handleAdd()  if the user is adding new transaction
  }

如您所见,我有两个函数,handleAdd 和 handleUpdate。但我需要根据用户的操作(更新或添加)调用其中一个,如果是更新,我需要获取事务 ID。

完成此任务的最佳方法是什么?我知道我不应该为添加和更新创建两个单独的表单

【问题讨论】:

    标签: reactjs forms components


    【解决方案1】:

    通常我创建一个表单来处理添加和更新。您必须以这种方式创建表单以接受默认数据集,如果提供,只需将它们加载到适当的控制字段中。

    我的controls 这个表单的道具看起来像这样:

    const controls = [
     {
        key: 'supa-dupa-key',
        type: 'text',
        label: 'whatever',
        required: true,
        alertText: 'Not today...',
        disabled: false,
        defaultValue: ''
      }
    ];
    

    我用它来填写我的常用表单本地状态,如果你想使用表单添加一些东西,只需通过不带defaultValue 的控件,如果你想使用表单更新,只需填写控件@987654324 @属性:

    fillUp = controls => ({
      ...controls.reduce((o, { key, defaultValue, type }) => ({
        ...o,
        [key]: {
          value: defaultValue || '',
          isValid: false,
          isInvalid: false
        }
      }), {})
    });
    

    每个控制字段都会根据控制键得到valueonChange

    value={this.state[key]}
    onChange={e => this.handleChange(e.target.value, key)}
    

    另外,我使用动态控件渲染来渲染来自 controls 属性的每个控件。 像这样(创建任意数量的类型):

    renderTextControl = control => (
      <Form.Group key={control.key} controlId={control.key}>
        <Form.Label className="mb-1 text-muted">
          {control.label}{control.required && ' *'}
        </Form.Label>
        <Form.Control
          disabled={this.props.inProgress || control.disabled || false}
          required={control.required || false}
          type={type}
          size="sm"
          isValid={this.state[control.key].isValid}
          isInvalid={this.state[control.key].isInvalid}
          value={this.state[control.key].value}
          onChange={this.handleChange(control.key, control.type)}
        />
        {control.alertText &&
          <Form.Control.Feedback type="invalid">
           {control.alertText}
          </Form.Control.Feedback>
        }
      </Form.Group>
    );
    

    我希望这可以帮助您,并且您可以根据自己的需要进行调整。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-14
      • 1970-01-01
      • 2021-02-13
      • 2012-05-27
      • 2012-12-20
      相关资源
      最近更新 更多