Установить начальное значение элемента формы, полученное через реквизит - PullRequest
0 голосов
/ 02 апреля 2019

Я использую 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}
/> 

1 Ответ

2 голосов
/ 02 апреля 2019

Полагаю, у вас возникла проблема с обновлением значений при изменении 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 и сохраните «oldProps» с помощью 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]);

  ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...