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

React Props为只读 为何两种场景修改props报错表现不一致

问题描述

以下是测试用的单页代码:

function Headline(props) {
  
  props.text = "I have changed.";
  
  return (
    <h1>{props.text}</h1>
  );
}

let title = <Headline text="Do Not Change" />;


let app = document.getElementById("app");
ReactDOM.createRoot(app).render(title);

React官方文档明确说明Props为只读属性,但运行上述单页代码时,可以成功修改props的值,页面最终输出为"I have changed.",全程没有抛出任何错误,和文档描述的规则存在差异。

按照以下步骤用create-react-app搭建项目复现相同逻辑时,却触发了props修改的报错:

  • 执行命令 npx create-react-app anything 初始化React项目。

项目安装完成后,在src目录下创建两个文件:
index.js 文件内容:

import React from 'react';
import ReactDOM from 'react-dom/client';
import Headline from './Headline';
import './index.css';

let title = <Headline text="Do Not Change" />;

let app = document.getElementById("root");
ReactDOM.createRoot(app).render(title);

Headline.js 文件内容:

function Headline(props) {

    props.text = "I have changed.";

    return (
        <h1>{props.text}</h1>
    );
    
}

export default Headline;

运行该CRA项目后,控制台会抛出props修改相关错误,错误截图如下:
props修改报错截图

为什么同样的修改props逻辑,单页运行时无报错,在create-react-app搭建的项目中却会抛出props可变错误?

原因说明

两种运行场景表现不一致,核心是React不同构建版本的校验逻辑不一样:

  • 单页直接引入的React运行时,默认是面向线上环境的生产构建版本。React仅在开发规范层面要求props只读,生产版本不会主动冻结props对象,也不会拦截对props的修改操作,所以修改props不会立刻抛出错误。但这种写法本身违反React单向数据流设计,后续组件触发重渲染时很容易出现数据不同步、渲染结果不符合预期的问题。
  • create-react-app生成的项目,开发环境默认开启严格模式,同时加载带完整开发校验的React构建版本:这个版本会主动冻结传入组件的props对象,任何尝试修改props的操作都会立刻在控制台抛出错误,目的是在开发阶段就提前拦截不符合规范的写法,避免问题流到线上。

注意:哪怕单页场景下修改props没有报错,也永远不要直接修改props的值。如果需要基于传入的props值做调整,应该将对应值拷贝到组件本地state中再操作,避免破坏React的数据流逻辑。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 20:42:16