我在这里做了一个演示:https : //codesandbox.io/s/interesting-germain-mgd64
如果你用一个人的名字输入一些东西,然后切换到另一个人并输入,你会看到它会将另一个人的名字改回原来的名字。但它为什么这样做是没有意义的。如果我删除整个 prevProps 和 nextProps 比较它工作正常。
虽然这在一个更简单的例子中工作得很好。我不确定为什么它在这种情况下不起作用。
就比较这里找到的props而言,我正在尝试做的更多细节:https : //reactjs.org/docs/react-api.html#reactmemo
使用备忘录的播放器组件在这里:
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
}
});
应用组件
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>
);
});