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



我正在使用 React Hooks 来处理一个简单的表单。我收到"交易"对象作为道具,我想基于此对象设置输入值,因为我正在尝试更新此"交易">

正如您在下面看到的,我正在尝试根据"交易"对象设置我的描述输入值,我将其作为 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>
  )
}

这个"事务"对象最初看起来像这样:

{
    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并使用useRef存储"oldProps":

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

相关内容

  • 没有找到相关文章

最新更新