Javascript 是否仍会触发重新渲染?
根据我对React的了解,您不应该变异任何对象,否则React不知道如何重新渲染,例如,单击按钮时,以下示例不应触发UI中的重新渲染:Javascript 是否仍会触发重新渲染?,javascript,reactjs,setstate,Javascript,Reactjs,Setstate,根据我对React的了解,您不应该变异任何对象,否则React不知道如何重新渲染,例如,单击按钮时,以下示例不应触发UI中的重新渲染: import React, { useState } from "react"; import ReactDOM from "react-dom"; function App({ input }) { const [items, setItems] = useState(input); return (
import React, { useState } from "react";
import ReactDOM from "react-dom";
function App({ input }) {
const [items, setItems] = useState(input);
return (
<div>
{items.map((item) => (
<MyItem item={item}/>
))}
<button
onClick={() => {
setItems((prevItems) => {
return prevItems.map((item) => {
if (item.id === 2) {
item.name = Math.random();
}
return item;
});
});
}}
>
Update wouldn't work due to shallow copy
</button>
</div>
);
}
function MyItem ({item}) {
const name = item.name
return <p>{name}</p>
}
ReactDOM.render(
<App
input={[
{ name: "apple", id: 1 },
{ name: "banana", id: 2 }
]}
/>,
document.getElementById("container")
);
为什么第1个版本工作正常,并且即使我只是更新原始项目对象,UI也会立即更新?渲染是由于创建了新数组的
.map
。如果您执行类似于prev[1].name=“x”的操作;返回上一个代码>在钩子中,这不会执行更新。带函数参数的Per onsetState
:
如果更新函数返回的值与当前值完全相同
状态下,将完全跳过后续重新加载程序
更新
是的,说到亲子互动,项目
将是相同的(通过引用),但子道具
将不同。你有MyItem({item})
,这个item
正在从props
解构,比如说MyItem(props)
,这个props
会因为父源的改变而改变
因此,每次映射列表时,都会明确要求父对象呈现其子对象,而子对象的部分(或全部)参数没有更改这一事实并不重要。为了证明这一点,您可以从子组件中删除任何参数:
{items.map(() => ( <MyItem /> ))}
{items.map(()=>())}
函数MyItem(){
returnhello
}
每次通过状态挂钩执行items
更新时,都将调用MyItem
。并且它的道具将始终与以前的版本不同。如果您的setItem设置了一个新对象
,则状态更改后的页面将重新呈现
在您的逻辑中,您执行了一个浅复制,它:
- 浅层复制创建了一个新对象,并从旧对象复制第一层的所有内容
浅复制和深复制还创建了一个新对象,它们都会在React中触发重新渲染
浅复制和深复制的不同之处在于:从旧对象的第二级开始,浅复制保留相同的对象,哪个深复制将在所有级别创建新对象。hmm,我知道map返回一个新数组,但这足以触发所有子组件的重新渲染?为什么我读了很多关于深入复制数组中的每个对象的帖子?例如-@Arch1tect请看一看,我扩展了答案,考虑了亲子问题。另外,我认为,您可能需要更新codesandbox演示,因为它目前不包括子组件。
{items.map(() => ( <MyItem /> ))}
function MyItem () {
return <p>hello</p>
}