Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/369.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 是否仍会触发重新渲染?_Javascript_Reactjs_Setstate - Fatal编程技术网

Javascript 是否仍会触发重新渲染?

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 (

根据我对React的了解,您不应该变异任何对象,否则React不知道如何重新渲染,例如,单击按钮时,以下示例不应触发UI中的重新渲染:

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 on
setState

如果更新函数返回的值与当前值完全相同 状态下,将完全跳过后续重新加载程序

更新

是的,说到亲子互动,
项目
将是相同的(通过引用),但子
道具
将不同。你有
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>
}