Reactjs 对“添加”和“更新”使用相同的表单组件。反应

Reactjs 对“添加”和“更新”使用相同的表单组件。反应,reactjs,forms,components,Reactjs,Forms,Components,我正在处理交易表。我只想添加、删除和更新表中的事务 我有一个“Transactions.js”功能组件,它具有事务状态(使用挂钩),我还有一个“TransactionForm.js”组件,它从“Transactions.js”接收“setTransactions”函数作为道具,以添加或更新事务状态 Transactions.js const [transactions, setTransactions] = useReducer( transactionsReducer, fetch

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

我有一个“Transactions.js”功能组件,它具有事务状态(使用挂钩),我还有一个“TransactionForm.js”组件,它从“Transactions.js”接收“setTransactions”函数作为道具,以添加或更新事务状态

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
  }
正如你所看到的,我有两个函数,handleud和handleUpdate。但是我需要根据用户的操作(更新或添加)调用其中一个,如果是更新,我还需要获取事务id


实现这一目标的最佳方式是什么?我知道我不应该为添加和更新创建两个单独的表单

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

我的
控件
此表单的道具如下所示:

const controls = [
 {
    key: 'supa-dupa-key',
    type: 'text',
    label: 'whatever',
    required: true,
    alertText: 'Not today...',
    disabled: false,
    defaultValue: ''
  }
];
我用它来填充我的通用表单本地状态,如果您想使用表单添加内容,只需传递不带
defaultValue
的控件,如果您想使用表单更新,只需填充控件
defaultValue
属性:

fillUp = controls => ({
  ...controls.reduce((o, { key, defaultValue, type }) => ({
    ...o,
    [key]: {
      value: defaultValue || '',
      isValid: false,
      isInvalid: false
    }
  }), {})
});
每个控制字段将根据控制键获得
值和
onChange

value={this.state[key]}
onChange={e => this.handleChange(e.target.value, key)}
此外,我还使用动态控件渲染从控件属性渲染每个控件。 类似这样的内容(创建任意数量的类型):

renderTextControl=control=>(
{control.label}{control.required&&'*'}
{control.alertText&&
{control.alertText}
}
);
我希望这能对你有所帮助,你可以根据自己的需要来调整

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>
);