在对象上进行反应和打字稿 useState

Rob*_*isk 5 typescript reactjs react-hooks

product我在 React 组件中有一个类型:

type TProduct = {
  name: string,
  price: string,
  stock: string
}
Run Code Online (Sandbox Code Playgroud)

我希望通过输入框更改我的组件中的值:

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 }})}
     />
    )
  }
Run Code Online (Sandbox Code Playgroud)

我认为通过添加...product它会复制其中所有相同的值product,并仅更改我想要的值,但这似乎不起作用。它将设置一个新的产品对象,尽管它只会使用最近输入的输入重写该对象的全部内容。

然后我尝试了一种不同的界面方法,其中:

interface IProduct {
  name: string;
  price:  string;
  stock: string;
}
Run Code Online (Sandbox Code Playgroud)

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

并使用与我之前展示的类似的状态更改,但可惜这只发生在另一个新错误中(我想我不确定如何在反应中正确使用接口)。

wen*_*jun 11

除了为输入上的事件提供方法之外,您还onChange需要指定。value例如,

value={product.name}
Run Code Online (Sandbox Code Playgroud)

此外,我不确定为什么product状态是深层嵌套的,因为在这种情况下不需要更深一层,这将降低当您需要更新每个事件的产品状态时的复杂性onChange。您只需传播当前产品状态,然后使用新值更新属性。例如,

setProduct({
  ...product, 
  name: e.target.value 
});
Run Code Online (Sandbox Code Playgroud)

此外,在输入产品状态时,无需断言 is as TProduct。鉴于属性可能未定义,您可以保留以下接口,

interface TProduct {
  name: string;
  price:  string;
  stock: string;
}
Run Code Online (Sandbox Code Playgroud)

并将键入设置为productas 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 })}
     />
    )
}
Run Code Online (Sandbox Code Playgroud)