我正在将React 16.6与实质性的UI配合使用,并且我在尝试避免不必要的重新渲染时遇到了非常糟糕的时机。我尝试了几乎所有可以想到的方法,并且在每次用户交互时都重新渲染了材料ui的子级组件。属性完全相同没关系,它们会被重新渲染。
我尝试使用备忘库react,并且根组件得到了备忘录,并避免了不必要的重新渲染,但是即使如此,我尝试过的所有react工具都将子组件检测为已重新渲染(react开发工具以及为什么更新软件包)
这是一个简单的代码段:
import React, { PureComponent, memo } from 'react';
import ListItem from '@material-ui/core/ListItem';
import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction';
import ListItemText from '@material-ui/core/ListItemText';
const rowText = ({ title, artist }) =>
console.log('Row text render') || (
<ListItemText primary={title} secondary={artist} />
);
const RowText = memo(rowText);
const row = ({ selected, song, onSelect, favorite, LikeButton }) =>
console.log('Row rendered') || (
<ListItem
button
selected={selected === song.title}
onClick={() => onSelect(song.title)}
>
{selected === song.title && <PlayArrowIcon color="primary" />}
<RowText {...song} />
<ListItemSecondaryAction>
<LikeButton liked={favorite} title={song.title} />
</ListItemSecondaryAction>
</ListItem>
);
row.displayName = 'Row';
const Row = memo(row);
Row rendered
Row text render
仅一次登录到控制台,但是据报告其余项(如ListItemSecondaryAction ListItemt和ListItemText)被重新呈现。这怎么可能 ?我希望备忘录能返回完全相同的对象,但要避免重新渲染
编辑:我尝试了我能想到的更彻底的解决方案:
class Row extends Component {
shouldComponentUpdate = (nextProps, nextState) => {
return false;
};
即使这样,我也会收到该组件所有子级都可以避免的重新渲染的消息
即使在最简单的组件(只有一个MUI组件)上,也无论如何都不会激怒我,我会得到不必要的重新渲染
class RowText extends Component {
shouldComponentUpdate = (nextProps, nextState) => {
return false;
};
render() {
const { title, artist } = this.props;
return <ListItemText primary={title} secondary={artist} />;
}
}
这一定是用户界面上的某种错误
编辑
这仅发生在ListItem组件及其子组件上,因此这一定是它们上的某种错误。我对其他组件尝试了相同的技术,如果子组件不应该重新渲染,则子组件不会重新渲染。