我正在渲染非常大的图像列表,当单独单击它们时,这些图像将添加到“查看器” div中。问题在于,即使未对列表内容进行任何更改,每次我向查看器添加图像时,原始列表也会重新呈现。
我尝试过在每个级别使用shouldComponentUpdate()
以及使用React.memo
。两者似乎都没有任何作用。我还研究了是否应该花费时间使组件发挥功能并研究钩子(useContext()
看起来很诱人),但是我在React还是太新了,无法知道这是否会浪费更多时间。 (请随意权衡这是否浪费时间。)
我不知道问题出在哪里,所以我不确定片段是否会带来很多好处。相反,我将问题简化了一下,并在此处发布了沙盒版本
https://codesandbox.io/s/async-darkness-l920b
此刻,我的shouldComponentUpdate
比较对于每个班级都非常简单;像这样:
if (nextProps.photoData === this.props.photoData) {
return false;
} else {
return true;
}
如果打开codesandbox控制台,您会看到我正在登录Year.js > <ImageList /> is rendering
来标记有问题的列表的每个后续呈现。
任何帮助,甚至是朝着正确方向前进的帮助,都将不胜感激。我一直在阅读博客文章,现在情况不错,似乎没有任何帮助。
答案 0 :(得分:1)
这是因为PhotoView
中的App.js
是在render方法中定义的,因此当状态更新导致渲染时,PhotoView
会重新定义。每次都是App组件的新组件。
请在渲染功能之外定义组件:
import React from "react";
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
import Year from "./Year";
import Viewer from "./Viewer";
import dataObj from "./dataObj.json";
import "./App.css";
class App extends React.Component {
constructor(props) {
super(props);
this.PhotoView = this.PhotoView.bind(this)
this.state = {
current: {
year: 2019,
url: ""
},
viewerData: [],
photoData: null
};
}
componentDidMount() {
this.setState({
photoData: dataObj
});
}
addToViewer = moment =>
this.setState(state => {
const viewerData = state.viewerData.concat(moment.props.data);
return {
viewerData,
value: ""
};
});
About() {
return (
<div>
<h1>About</h1>
</div>
);
};
PhotoView(url) {
return (
<div className="PhotoView">
<Year
setCurrent={this.setCurrent}
photoData={this.state.photoData}
addToViewer={this.addToViewer}
/>
<Viewer
viewerData={this.state.viewerData}
setCurrent={this.setCurrent}
/>
</div>
);
}
render() {
return (
<div className="App">
<Router>
<nav>
<Link to="/about">About</Link>
<Link to="/">Photo View</Link>
</nav>
<Switch>
<Route path="/about" exact component={this.About} />
<Route path="/" component={this.PhotoView} />
</Switch>
</Router>
</div>
);
}
}
export default App;
或将它们移至单个文件。