设置通过 props 接收的表单元素初始值

Set form element initial value which is received via props

我正在使用 React Hooks 来处理一个简单的表单。我收到 'transaction' 对象作为道具,我想根据这个对象设置输入值,因为我正在尝试更新这个 'transaction'

正如您在下面看到的,我正在尝试根据 'transaction' 对象设置我的描述输入值,我收到的是 prop

//TransactionsForm.js

const TransactionsForm = ({ onSubmit, transaction }) => {

  const [values, setValues] = useState({
    description: transaction.description
  })

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

  return (
    <form>      
          <input
            type="text"
            placeholder="description"
            name="description"
            value={values.description}
            onChange={handleChange}
          /> 
        <button>Submit</button>
    </form>
  )
}

这个 'transaction' 对象最初看起来像这样:

{
    id: null,
    description: '',
    transactionType: '',
    date: '',
    category: '',
    amount: ''
}

但后来我更新了它,当用户单击编辑按钮并将其设置为单击的交易对象以传递给我的 TransactionsForm.js 并因此更新基于此的表单输入值。

如果我这样设置我的输入值

<input
   type="text"
   placeholder="description"
   name="description"
   value={transaction.description} // like this it's working, but when I use values.description the value is not updating
   onChange={handleChange}
/> 

我猜你在 TransactionsForm 道具改变时更新值有问题。 useState 仅在第一次渲染时设置初始值,并且在道具更改时不更新它。您需要手动完成:

const TransactionsForm = ({ onSubmit, transaction }) => {

  const [values, setValues] = useState({
    description: transaction.description
  });

  useEffect(() => setValues(
    oldValues => (
      {...oldValues, description: transaction.description}
    )
  ), [transaction.description]);

  ...

useEffect 将在初始渲染时调用,并且每次 transaction.description 都会获得一个新值。由于 setValues 收到一个新对象,您将在初始对象之后获得不必要的额外渲染。为避免这种情况,您只能在您的州中存储 description

const [descripton, setDescription] = useState(transaction.description);

如果你真的需要一个复杂的状态结构,考虑使用useReducer and store "oldProps" with useRef:

const TransactionsForm = ({ onSubmit, transaction }) => {

  const [values, setValues] = useState({
    description: transaction.description
  });
  const oldDescription = useRef(transaction.description);

  useEffect(() => {
    if (oldDescription.current !== transaction.description) {
      oldDescription.current = transaction.description;
      setValues(
        oldValues => (
          {...oldValues, description: transaction.description}
        )
      );
    }
 }, [transaction.description]);

  ...