Javascript 比较React.memo组件中的prevProps和nextProps以防止不必要的重新渲染,但它';他表现得很滑稽
我在这里做了一个演示: 如果你用一个人的名字输入了一些东西,然后切换到另一个人并四处键入,你会看到它会将另一个人的名字改回原来的名字。但它为什么这么做是没有道理的。如果我删除整个prevProps和nextProps比较,效果会很好 虽然这在一个更简单的例子中有效,但很好。但我不确定为什么在这种情况下它不起作用 关于我试图做什么的更多详细信息,如比较这里找到的道具: 使用备忘录的播放器组件如下所示:Javascript 比较React.memo组件中的prevProps和nextProps以防止不必要的重新渲染,但它';他表现得很滑稽,javascript,reactjs,Javascript,Reactjs,我在这里做了一个演示: 如果你用一个人的名字输入了一些东西,然后切换到另一个人并四处键入,你会看到它会将另一个人的名字改回原来的名字。但它为什么这么做是没有道理的。如果我删除整个prevProps和nextProps比较,效果会很好 虽然这在一个更简单的例子中有效,但很好。但我不确定为什么在这种情况下它不起作用 关于我试图做什么的更多详细信息,如比较这里找到的道具: 使用备忘录的播放器组件如下所示: export const Player = React.memo(({player, modif
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
。但这也意味着每次DependencyplayerDict
更改(每次更改事件)时,您将获得一个新的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
}
}
编辑:此处更新的演示代码将在几个小时后开始工作,非常感谢!会让你知道的!哦,天哪,就是这样?我真的很喜欢你解释了为什么这能帮助我理解。。。非常感谢你,你是男子汉,是的,这是一个很小的改变,产生了很大的不同。谢谢你的反馈,我很高兴能帮上忙!