对对象进行反应并打字稿useState

I have a type product within a react component:

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

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

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 }})}
     />
    )
  }

I thought by adding ...product it would copy over all the same values within product and just change the value I wanted to but that didn't seem to work. It would set a new product object although it would just rewrite the whole content of the object with the only the most recent entered input.

然后,我尝试使用以下接口的其他方法:

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

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

并使用了与我之前显示的状态更改类似的方法,但是可惜的是,这种更改仅发生在另一个新错误中(我想我不确定如何在React中正确使用接口)。

评论
  • dquis
    dquis 回复

    Apart from supplying the methods for the onChange events on the inputs, you will need to specify the value as well. For instance,

    value={product.name}
    

    In addition, you have went one level too deep when you update the product state on each of the onChange events. You only need to spread the current product state, followed by updating the property with the new values. For instance,

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

    Last but not least, if you are working with the newer versions of React, it will be sufficient to type your component as React.FC.

    这就是您的组件的外观。

    const AddProductCard: React.FC = () => {
      const classes = useStyles();
      const [product, setProduct] = React.useState({ product:{} as 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 })}
         />
        )
    }
    
  • ret
    ret 回复

    您想传播到一个新对象中,然后覆盖所需的属性,例如

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

    Although, given you are setting just product you might want to not making it a nested property of the state and just making it the state itself.