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

React Native+TypeScript状态更新报错:Attempted to assign readonly property

问题分析与修复

错误原因

你遇到的问题根源在父组件的changeVal函数里:

  • 直接修改了传入的formData(也就是userDetails状态对象),React状态是不可变的,直接修改会破坏状态管理机制。
  • setUserDetails((formData[entry] = val))这行代码里,赋值表达式返回的是val,所以第一次更新后,userDetails会从对象变成字符串(比如你输入的用户名)。后续输入时,formData已经是字符串,字符串的属性是只读的,所以触发“Attempted to assign readonly property”错误。

修复方案

父组件修改

把changeVal改成正确的不可变更新方式,用函数式更新获取最新状态,创建新对象覆盖对应属性:

const ProfileEdit: React.FC<Props> = ({ setIsModalOpen }) => {
  const user = useSelector(state => state.userData.user);

  const [userDetails, setUserDetails] = useState({
    username: user.username,
    firstName: user.userName,
    lastName: user.lastName,
    gender: user.gender,
    dateOfBirth: user.dateOfBirth,
    city: user.city
  });

  // 修正后的更新函数,不需要传入formData,直接用prevState获取最新状态
  const changeVal = (entry, val) => {
    setUserDetails(prevState => ({
      ...prevState,
      [entry]: val
    }));
  };

  return (
    <Modal animationType="slide">
      <Container>
        <EditProfileInput
          inputTitle="Username"
          changeVal={changeVal}
          entry="username"
        />
      </Container>
    </Modal>
  );
};

子组件修改

不需要再传递formData,直接调用changeVal时传入entry和输入值即可:

// Child Component
const EditProfileInput: React.FC<Props> = ({
  inputTitle,
  changeVal,
  entry
}) => {
  return (
    <Container>
      <InputHeader>{inputTitle}</InputHeader>
      <Input>
        <InputText
          name={inputTitle}
          onChangeText={text => changeVal(entry, text)}
        />
      </Input>
    </Container>
  );
};

额外说明

  • 函数式更新(setUserDetails(prevState => ...))可以确保每次更新都基于最新的状态,避免闭包导致的旧状态问题。
  • 用展开运算符...prevState创建新对象,保证状态的不可变性,符合React的状态管理规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 14:05:17