You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React JS与TypeScript:无法赋值只读属性'title'报错问题

React输入框追加内容时出现只读属性赋值错误

点击Add按钮时输入值能正常保存到reducer,但在输入框中追加内容时,抛出以下错误:

Cannot assign to read only property 'title' of object '#'
TypeError: Cannot assign to read only property 'title' of object '#'

用户提供的React组件代码如下:

import React, { useState } from "react";
import Button from "react-bootstrap/Button";
import Form from "react-bootstrap/Form";
import InputGroup from "react-bootstrap/InputGroup";
import { Product, addProduct } from "../Slice/ProductsSlice";
import { useAppDisptach } from "../store";

const ProductForm: React.FC = () => {
  const dispatch = useAppDisptach();

  const [product, setProduct] = useState<Product>({
    id: "",
    title: "",
    price: 0,
  });

  const { id, title, price } = product;

  const handleChange = ({ target: { name, value } }: React.ChangeEvent<HTMLInputElement>) => setProduct((prev) => {
    console.log('handleChange - ', prev);
    (prev as any)[name] = value;
    const newValue = { ...prev };
    return newValue;
  });

  const handleSubmit = (event: React.FormEvent) => {
    event.preventDefault();
    dispatch(addProduct(product));

  }

  return (
    <div>
      <h2>Add Game to the Store</h2>
      <InputGroup className="mb-3">
        <Form.Control
          placeholder="Games Title"
          aria-label="Games Title"
          name={`title`}
          value={title}
          onChange={handleChange}
        />
        <Form.Control
          placeholder="Price"
          aria-label="Price"
          name={`price`}
          type="number"
          value={price}
          onChange={handleChange}
        />
        <Form.Control
          placeholder="Id"
          aria-label="Id"
          name={`id`}
          value={id}
          onChange={handleChange}
        />
      </InputGroup>
      <Button onClick={handleSubmit}>Add Product</Button>
    </div>
  );
};

问题根源

在handleChange函数里,你直接修改了setProduct回调返回的prev状态对象——React的状态是不可变的,这个prev对象被标记为只读,直接赋值就会触发报错。

修复代码

把handleChange改成不直接修改原对象的写法,通过展开运算符创建新对象并更新对应属性,同时注意price字段的类型转换:

const handleChange = ({ target: { name, value } }: React.ChangeEvent<HTMLInputElement>) => setProduct((prev) => {
  console.log('handleChange - ', prev);
  // 直接返回新对象,不修改原prev
  return {
    ...prev,
    [name]: name === 'price' ? Number(value) : value // price字段转成数字类型
  };
});

内容的提问来源于stack exchange,提问作者Pradeep

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 17:17:07