首页 > 解决方案 > 为什么 value 属性将输入呈现为只读而 defaultValue 将其呈现为读写?

问题描述

所以我有一个购物车,每次添加相同的商品时,添加的商品数量都会动态增加+1,并且在购物车本身内,添加商品的数量可以通过任何首选用户编号手动更改。

如果我value=""在输入字段中使用该属性,则该值会正确动态更新,但不允许我手动更改该值。如果我使用defaultValue=""的值不会在每次添加项目时正确更新,但允许我根据需要手动更改值。

我如何才能正确显示动态值并能够根据需要更新值字段?我的代码如下:

class CartItem2 extends Component {
    constructor(props) {
        super(props);
    }
    handleChange = e => {
      const { name, type, value } = e.target;
      const val = type === 'number' ? parseFloat(value) : value;
      this.setState(() => { return { [name]: val }});
    };
    updateCartItem = async (e, updateCartItemMutation) => {
      e.preventDefault();
      console.log('Updating Cart Item!!');
      console.log(this.state);
      const res = await updateCartItemMutation({
        variables: {
          id: this.props.cartItem.id,
          quantity: this.state.quantity,
        },
      });
      console.log('Updated!!');
    };
    static getDerivedStateFromProps(nextProps, prevState){
        if (nextProps.cartItem.quantity !== prevState.quantity) {
            console.log("nextProps ", nextProps);
            console.log("prevState", prevState);
            return {quantity: nextProps.cartItem.quantity};
        }
        else return null;
    }

    render() {
        const { cartItem, client } = this.props;
        const { quantity } = this.state;

        return (
            <CartItemStyles>
                <img width="100" src={cartItem.item.image} alt={cartItem.item.title} />
                <div className="cart-item-details">
                <h3>{cartItem.item.title}</h3>
                <p>
                    {formatMoney(cartItem.item.price * cartItem.quantity)}
                    {' - '}
                    <em>
                        {cartItem.quantity} &times; {formatMoney(cartItem.item.price)} each
                    </em>
                </p>
                <Mutation 
                    mutation={UPDATE_CART_ITEM_MUTATION} 
                    variables={this.state}
                >
                    {(updateCartItem, { loading, error }) => {
                    return (
                        <Form2 key={cartItem.id} onSubmit={e => this.updateCartItem(e, updateCartItem)}>
                        <Error error={error} />
                        <label htmlFor="quantity">
                        <input
                            type="number"
                            id="quantity"
                            name="quantity"
                            placeholder="Quantity"
                            required
                            value={quantity}
                            onChange={this.handleChange}
                        />
                        </label>
                        <button type="submit">Updat{loading ? 'ing' : 'e'}</button>
                        </Form2>
                    )
                    }}
                </Mutation>
                </div>
            <RemoveFromCart id={cartItem.id} />
          </CartItemStyles>
        );
    }
}

如果你去这里:flamingo-next-production.herokuapp.com,使用 testing123@123.com 和 testing123 登录,然后单击 shop,然后单击购物车,然后将相同商品的倍数添加到购物车,然后转到购物车尝试并手动更改项目值。

标签: htmlreactjs

解决方案


看起来您正在使用该状态的默认值进行受控输入?如果是这样,您需要将状态中的初始数量设置为该cartItem.quantity值。

下面缺少很多参考资料,但您应该明白这一点。

class CartItem extends Component {
  constructor(props) {
    super(props);

    this.state = {
      quantity: props.cartItem.quantity,
    };
  }


  handleChange = e => {
    const { name, type, value } = e.target;
    const val = type === 'number' ? parseFloat(value) : value;

    this.setState({ [name]: val });
  };

  render() {
    const { quantity } = this.state;

    return (
      <Mutation
        mutation={UPDATE_CART_ITEM_MUTATION}
        variables={this.state}
      >
        {(updateCartItem, { loading, error }) => {
          return (
            <Form2 onSubmit={e => this.updateCartItem(e, updateCartItem)}>
              <Error error={error} />
              <label htmlFor="quantity">
                <input
                  type="number"
                  id="quantity"
                  name="quantity"
                  placeholder="Quantity"
                  value={quantity}
                  onChange={this.handleChange}
                  required
                />
              </label>
              <button type="submit">Updat{loading ? 'ing' : 'e'}</button>
            </Form2>
          )
        }}
      </Mutation>
    )
  }
}

推荐阅读