реагировать и печатать useState на объекте - PullRequest
1 голос
/ 07 февраля 2020

У меня есть тип product в компоненте React:

type TProduct = {
  name: string,
  price: string,
  stock: string
}

, в котором мой компонент I sh изменяет значения через поле ввода:

const AddProductCard: React.SFC = () => {
  const classes = useStyles();
  const [product, setProduct] = React.useState({ product:{} as TProduct})
  return (
     <input 
      onChange={e => setProduct({...product ,product: {name: e.target.value }})}
     />
     <input 
      onChange={e => setProduct({...product ,product: {stock: e.target.value }})}
     />
     <input 
      onChange={e => setProduct({...product ,product: {price: e.target.value }})}
     />
    )
  }

Я подумал, добавив ...product, он скопирует все те же значения в product и просто изменит значение, которое я хотел, но это, похоже, не сработало. Он установит новый объект продукта, хотя он просто перезапишет все содержимое объекта с использованием только самых последних введенных данных.

Затем я попытался использовать другой подход с интерфейсом, в котором:

interface IProduct {
  name: string;
  price:  string;
  stock: string;
}

и

const [product, setProduct] = React.useState<IProduct | undefined>(undefined);

и использовал такое же изменение состояния как I показали ранее, но увы, это произошло только в другой новой ошибке (я думаю, я не уверен, как правильно использовать интерфейс в реакции).

Ответы [ 2 ]

2 голосов
/ 07 февраля 2020

Помимо предоставления методов для событий onChange на входах, вам также потребуется указать value. Например,

value={product.name}

Кроме того, я не уверен, почему состояние product глубоко вложено, поскольку нет необходимости go на один уровень глубже в этом сценарии. Это снизит сложность. когда вам нужно обновить состояние продукта для каждого из событий onChange. Вам нужно только распространить текущее состояние продукта с последующим обновлением свойства новыми значениями. Например,

setProduct({
  ...product, 
  name: e.target.value 
});

Кроме того, когда дело доходит до ввода состояния продукта, нет необходимости утверждать, как TProduct. Учитывая, что свойства могут быть неопределенными, вы можете сохранить следующий интерфейс,

interface TProduct {
  name: string;
  price:  string;
  stock: string;
}

и установить для product значения Partial<TProduct>.

И последнее, но не менее важное, если вы работают с более новыми версиями React, вам будет достаточно набрать ваш компонент как React.FC.

Вот так должен выглядеть ваш компонент.

const AddProductCard: React.FC = () => {
  const classes = useStyles();
  const [product, setProduct] = React.useState<Partial<TProduct>>({});

  return (
     <input 
      value={product.name || ''}
      onChange={e => setProduct({...product, name: e.target.value })}
     />
     <input 
      value={product.stock || ''}
      onChange={e => setProduct({...product, stock: e.target.value })}
     />
     <input 
      value={product.price || ''}
      onChange={e => setProduct({...product, price: e.target.value })}
     />
    )
}
1 голос
/ 07 февраля 2020

Вы хотите распространиться на новый объект, а затем переопределить нужные вам свойства, например,

setProduct({ 
  product: {
    ...product,
    name: e.target.value
  }
});

Хотя, учитывая, что вы устанавливаете просто product, вы можете не делать его вложенным свойством государство и просто делает его самим государством.

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