Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/462.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 比较React.memo组件中的prevProps和nextProps以防止不必要的重新渲染,但它';他表现得很滑稽_Javascript_Reactjs - Fatal编程技术网

Javascript 比较React.memo组件中的prevProps和nextProps以防止不必要的重新渲染,但它';他表现得很滑稽

Javascript 比较React.memo组件中的prevProps和nextProps以防止不必要的重新渲染,但它';他表现得很滑稽,javascript,reactjs,Javascript,Reactjs,我在这里做了一个演示: 如果你用一个人的名字输入了一些东西,然后切换到另一个人并四处键入,你会看到它会将另一个人的名字改回原来的名字。但它为什么这么做是没有道理的。如果我删除整个prevProps和nextProps比较,效果会很好 虽然这在一个更简单的例子中有效,但很好。但我不确定为什么在这种情况下它不起作用 关于我试图做什么的更多详细信息,如比较这里找到的道具: 使用备忘录的播放器组件如下所示: export const Player = React.memo(({player, modif

我在这里做了一个演示:

如果你用一个人的名字输入了一些东西,然后切换到另一个人并四处键入,你会看到它会将另一个人的名字改回原来的名字。但它为什么这么做是没有道理的。如果我删除整个prevProps和nextProps比较,效果会很好

虽然这在一个更简单的例子中有效,但很好。但我不确定为什么在这种情况下它不起作用

关于我试图做什么的更多详细信息,如比较这里找到的道具:

使用备忘录的播放器组件如下所示:

export const Player = React.memo(({player, modifyPlayer}) => {
  const handleOnChange = React.useCallback((event) => {
    modifyPlayer(player.id, event.target.name, event.target.value);
  }, [player, modifyPlayer]);

  return (
    <div>
      <input type={"text"} name={"firstName"} value={player.firstName} onChange={handleOnChange}/>
      <input type={"text"} name={"lastName"} value={player.lastName} onChange={handleOnChange}/>
    </div>
  );
}, 
(prevProps, nextProps) => {
  // Check to see if the data is the same
  if (prevProps.player.firstName === nextProps.player.firstName
    && prevProps.player.lastName === nextProps.player.lastName
    && prevProps.player.id === nextProps.player.id) {
    return true; // Return true if they ARE the same
  } else {
    return false; // Return false if they are NOT the same
    // EVEN THOUGH THIS RETURNS FALSE IT MESSES UP THE OTHER TEXT
  }
});
export const Player=React.memo({Player,modifyPlayer})=>{
const handleOnChange=React.useCallback((事件)=>{
modifyPlayer(player.id、event.target.name、event.target.value);
},[player,modifyPlayer]);
返回(
);
}, 
(prevProps,nextProps)=>{
//检查数据是否相同
如果(prevProps.player.firstName==nextProps.player.firstName
&&prevProps.player.lastName==nextProps.player.lastName
&&prevProps.player.id==nextrops.player.id){
return true;//如果它们相同,则返回true
}否则{
return false;//如果它们不相同,则返回false
//即使返回FALSE,它也会弄乱其他文本
}
});
应用程序组件

function App() {
  const [playerDict, setPlayerDict] = React.useState(
    {
      id1: {
        firstName: "John",
        lastName: "Doe",
        id: 'id1'
      },
      id2: {
        firstName: "Michael",
        lastName: "Creaton",
        id: 'id2'
      },
      id3: {
        firstName: "William",
        lastName: "Shakespeare",
        id: 'id3'
      },
    }

  );
  const [playerIdList, setPlayerIdList] = React.useState(['id1', 'id2', 'id3']);

  const modifyPlayer = React.useCallback((playerId, propertyName, value) => {
    const playerCopy = {...playerDict[playerId]};
    playerCopy[propertyName] = value;
    const playerDictCopy = {
      ...playerDict,
      [playerId]: playerCopy
    };
    setPlayerDict(playerDictCopy);
  }
  ,[playerDict]);

  return (
    <div>
      <Playlist
        modifyPlayer={modifyPlayer}
        playlist={playerIdList.map(playerId => playerDict[playerId])}
      />
    </div>
  );
}
export const Playlist = React.memo(({modifyPlayer, playlist}) => {
  return (
    <div>
      {
        playlist.map((player) => (
          <Player
            key={player.id}
            player={player}
            modifyPlayer={modifyPlayer}
          />
        ))
      }
    </div>
  );
});
函数应用程序(){
const[playerDict,setPlayerDict]=React.useState(
{
id1:{
名字:“约翰”,
姓:“Doe”,
id:'id1'
},
id2:{
名字:“迈克尔”,
姓氏:“Creaton”,
id:'id2'
},
id3:{
名字:“威廉”,
姓氏:“莎士比亚”,
id:'id3'
},
}
);
const[playerIdList,setPlayerIdList]=React.useState(['id1','id2','id3']);
const modifyPlayer=React.useCallback((playerId,propertyName,value)=>{
const playerCopy={…playerDict[playerId]};
playerCopy[propertyName]=值;
常量playerDictCopy={
…玩家信息技术,
[玩家ID]:玩家副本
};
setPlayerDict(playerDictCopy);
}
,[playerDict]);
返回(
playerDict[playerId])]
/>
);
}
播放列表组件

function App() {
  const [playerDict, setPlayerDict] = React.useState(
    {
      id1: {
        firstName: "John",
        lastName: "Doe",
        id: 'id1'
      },
      id2: {
        firstName: "Michael",
        lastName: "Creaton",
        id: 'id2'
      },
      id3: {
        firstName: "William",
        lastName: "Shakespeare",
        id: 'id3'
      },
    }

  );
  const [playerIdList, setPlayerIdList] = React.useState(['id1', 'id2', 'id3']);

  const modifyPlayer = React.useCallback((playerId, propertyName, value) => {
    const playerCopy = {...playerDict[playerId]};
    playerCopy[propertyName] = value;
    const playerDictCopy = {
      ...playerDict,
      [playerId]: playerCopy
    };
    setPlayerDict(playerDictCopy);
  }
  ,[playerDict]);

  return (
    <div>
      <Playlist
        modifyPlayer={modifyPlayer}
        playlist={playerIdList.map(playerId => playerDict[playerId])}
      />
    </div>
  );
}
export const Playlist = React.memo(({modifyPlayer, playlist}) => {
  return (
    <div>
      {
        playlist.map((player) => (
          <Player
            key={player.id}
            player={player}
            modifyPlayer={modifyPlayer}
          />
        ))
      }
    </div>
  );
});
export const Playlist=React.memo({modifyPlayer,Playlist})=>{
返回(
{
playlist.map((播放器)=>(
))
}
);
});

这是一个很好的难题,但我想我发现了问题所在

创建回调
modifyPlayer
时,您正确地将
playerDict
作为依赖项传递,因为回调依赖于在使用最新更新事件创建新版本的
playerDict
之前拥有“最新”版本的
playerDict
。但这也意味着每次Dependency
playerDict
更改(每次更改事件)时,您将获得一个新的
modifyPlayer
-回调函数

但是
Player
-组件(第29行附近)中的
areEqual
函数表示,只有当
Player
的任何属性(id、firstName或lastName)发生更改时,组件才应该更新,这意味着组件从未收到更新的回调函数,因此,它将尝试使用数据的“错误”早期版本更新
playerDict
(因为它具有回调函数的早期版本)

包括检查
prevProps.modifyPlayer
nextrops之间是否相等。modifyPlayer
使代码再次按预期运行:

// in Player.js - around line 29
(prevProps, nextProps) => {
    // Check to see if the data is the same
    if (
      prevProps.player.firstName === nextProps.player.firstName &&
      prevProps.player.lastName === nextProps.player.lastName &&
      prevProps.player.id === nextProps.player.id && 
      prevProps.modifyPlayer === nextProps.modifyPlayer
    ) {
      return true; // Return true if they ARE the same
    } else {
      return false; // Return false if they are NOT the same
    }
  }

编辑:此处更新的演示代码

将在几个小时后开始工作,非常感谢!会让你知道的!哦,天哪,就是这样?我真的很喜欢你解释了为什么这能帮助我理解。。。非常感谢你,你是男子汉,是的,这是一个很小的改变,产生了很大的不同。谢谢你的反馈,我很高兴能帮上忙!