理想是火,点燃熄灭的灯。
如果必须要在子组件修改这个props,需要先把这个props赋值给state,并进行深度拷贝
不然会污染父组件的state,因为没有深度拷贝之前,他们的引用内存地址是一致的,所以就导致父组件和子组件都改变了
超出了props - 只读的预期
相关代码示例:
父组件
import React, { Component } from "react"; import Test from "../components/Test"; class Router2 extends Component { constructor(props) { super(props); this.state = { a: [ { value: "1", }, ], b: { name: "bill", }, show: false, }; } render() { const { a, show, b } = this.state; return ( <h2> Router2 <div> a: {a.map((item, index) => { return <input type="text" value={item.value} key={index} />; })} b: {b.name} </div> {show ? ( <button onClick={() => this.setState({ show: false })}>隐藏</button> ) : ( <button onClick={() => this.setState({ show: true })}>展示</button> )} {show && <Test a={a} b={b} />} </h2> ); } } export default Router2;
子组件
import React, { useEffect, useState } from "react"; const Test = ({ a, b }) => { const [a_state, setA_state] = useState(a); const [b_state, setB_state] = useState(b); const setValue = (e) => { a_state[0].value = e.target.value; setA_state([...a_state]); }; const changeName = () => { b.name = `bill pang !!!!!!`; let _b = JSON.parse(JSON.stringify(b)); setB_state(_b); }; useEffect(() => { console.log("a__", a); console.log("b__", b); }, []); return ( <div> a_state: <br /> {a_state.map((item, index) => { return ( <input type="text" value={item.value} key={index} onChange={setValue} /> ); })} b_state: <br /> {b_state.name} <button onClick={changeName}>修改名称</button> </div> ); }; export default Test;
react 的组件更新,是基于一个**“浅比较”机制**:
state
和上一次 state
的引用是否不同(===)const [person, setPerson] = useState({ name: "Alice", age: 20 }); const updateAge = () => { person.age = 21; // ❌ 修改了 state 对象的内容 setPerson(person); // ❌ 传的还是原来的引用 };
React 会这样判断:
previousState === nextState // 结果是 true,认为“没变”
➡️ React 不会触发组件重新渲染!
但其实你已经偷偷改了内部数据,这就造成了页面和真实数据不一致的问题。
const updateAge = () => { setPerson({ ...person, age: 21 }); // ✅ 新的对象引用 };
现在:
previousState === nextState // false,React 检测到“变了”
➡️ React 会重新渲染组件 ✅
props
不允许,违反数据单向流原则
只能读,不能改
state
改了内容但引用没变 → 无法触发更新
使用新对象/数组引用触发更新
作者: Bill 本文地址: http://biaoblog.cn/info?id=1747637394799
版权声明: 本文为原创文章,版权归 biaoblog 个人博客 所有,欢迎分享本文,转载请保留出处,谢谢!