Javascript 优化React-Redux连接的PureComponent
我在尝试优化React Redux应用程序时遇到了一个非常令人沮丧的问题 我有一个header组件,每次对redux存储进行更改时都会重新加载它。我的头组件是一个PureComponent 我已经安装了为什么要更新,它告诉我:Javascript 优化React-Redux连接的PureComponent,javascript,reactjs,performance,optimization,redux,Javascript,Reactjs,Performance,Optimization,Redux,我在尝试优化React Redux应用程序时遇到了一个非常令人沮丧的问题 我有一个header组件,每次对redux存储进行更改时都会重新加载它。我的头组件是一个PureComponent 我已经安装了为什么要更新,它告诉我: Header.props:值未更改。可避免的重新渲染 这是我的组件: export class Header extends PureComponent { logout() { // this.props.logout(); }
Header.props:值未更改。可避免的重新渲染代码>
这是我的组件:
export class Header extends PureComponent {
logout() {
// this.props.logout();
}
signup = () => {
this.props.history.push(urls.SIGNUP)
}
render() {
console.log("=============== RELOADING HEADER")
return (
<div>
<HeaderContent
logout={this.logout.bind(this)}
signup={this.signup.bind(this)}
user={this.props.user}/>
</div>
)
}
}
export function mapStateToProps(store) {
// EDITTED: I initially thought this was causing the problem
// but i get the same issue when returning a javascript object
//const u = loginUserFactory(store);
const u ={}
return {
user: u,
}
}
export function mapDispatchToProps(dispatch) {
return {
logout: function l() {
dispatch(authActions.logout())
}
}
}
export function mergeProps(propsFromState,propsFromDispatch,ownProps) {
return {
// logout: function logout() {
// propsFromDispatch.logout()
// },
...propsFromState,
...ownProps
}
}
let HeaderContainer = connect(
mapStateToProps,
mapDispatchToProps,
mergeProps,
{pure: true}
)(Header)
export default withRouter(HeaderContainer);
Header.propTypes = {
history: PropTypes.object.isRequired,
user: PropTypes.object.isRequired,
logout: PropTypes.func.isRequired,
}
我猜loginUserFactory()
每次调用它时都会创建一个新的用户对象,也就是每次更新存储时都会创建一个新的用户对象,因此总是将一个新的用户对象传递给您的组件,而这个新的用户对象并不等于以前的用户对象
此外,您的标题
对用户没有任何作用,只是将其进一步向下传递到树中。相反,您应该连接HeaderContent
组件,只将用户对象的属性映射到它实际需要的属性,例如名称
一般来说,MapStateTrops()
不应该有任何副作用。它应该只过滤/排序/计算给定状态和自身道具的连接组件的道具。在最简单的情况下,它只不过是从存储中返回属性的子集。我猜loginUserFactory()
每次调用它时都会创建一个新的用户对象,这是每次存储更新时都会创建一个新的用户对象,因此总是向组件传递一个不等于前一个的新用户对象
此外,您的标题
对用户没有任何作用,只是将其进一步向下传递到树中。相反,您应该连接HeaderContent
组件,只将用户对象的属性映射到它实际需要的属性,例如名称
一般来说,MapStateTrops()
不应该有任何副作用。它应该只过滤/排序/计算给定状态和自身道具的连接组件的道具。在最简单的情况下,它只会从存储中返回属性的子集。您正在单击处理程序中使用bind
。不,不,不!当您在处理程序内部绑定时,每个重新加载程序将创建一个全新的函数实例。在构造函数中绑定或将单击处理程序方法转换为箭头函数
handleClick = () => {
}
// or
constructor() {
super()
this.handleClick = this.handleClick.bind(this)
}
另外,请勿在mapStateToProps
或mapDispatchToProps
中执行任何操作或算法。这些也会触发重播。将该逻辑放在其他地方。您正在单击处理程序中使用bind
。不,不,不!当您在处理程序内部绑定时,每个重新加载程序将创建一个全新的函数实例。在构造函数中绑定或将单击处理程序方法转换为箭头函数
handleClick = () => {
}
// or
constructor() {
super()
this.handleClick = this.handleClick.bind(this)
}
另外,请勿在mapStateToProps
或mapDispatchToProps
中执行任何操作或算法。这些也会触发重播。将该逻辑放在其他地方。有没有办法创建一个不会每次都导致更新的用户对象?@user1795370我认为更好的解决方案是在每次更新商店中的任何内容时都不创建用户对象。它应该在用户登录时执行一次,然后保持不变。@user1795370您可以提供loginUserFactory()
的代码,这样我们就可以看到它的作用了吗?我可以看到为什么我所做的是错的。在某些情况下,拥有一个对象真的很有帮助,因为有一些方法与我希望保存在单个文件中的对象相关联。有更好的方法吗?@user1795370是此方法返回一个新的用户对象。您可以通过在用户登录到仅从您的商店映射该对象的应用程序时只创建该对象一次来避免这种情况。一般来说,mapStateToProps
不应该有任何副作用。有没有办法创建一个用户对象,而不会每次都导致更新?@user1795370我认为更好的解决方案是不要每次更新商店中的任何内容时都创建一个用户对象。它应该在用户登录时执行一次,然后保持不变。@user1795370您可以提供loginUserFactory()
的代码,这样我们就可以看到它的作用了吗?我可以看到为什么我所做的是错的。在某些情况下,拥有一个对象真的很有帮助,因为有一些方法与我希望保存在单个文件中的对象相关联。有更好的方法吗?@user1795370是此方法返回一个新的用户对象。您可以通过在用户登录到仅从您的商店映射该对象的应用程序时只创建该对象一次来避免这种情况。一般来说,mapstatetrops
不应该有任何副作用。好的,我在代码中更改了它,但我仍然遇到同样的问题您从mapstatetrops
中删除了逻辑,并将您的单击处理程序绑定为不创建新实例,但仍然存在性能问题?检查火焰图,看看你是否在其他地方遇到了问题。好的,我在代码中对其进行了更改,但仍然遇到相同的问题您从mapStateToProps
中删除了逻辑,并将您的单击处理程序绑定为不创建新实例,但仍存在性能问题?检查火焰图,看看你是否在其他地方遇到了问题。您仍在创建新的用户对象const u={}
将在每次调用MapStateTops
时创建一个新的空对象(每次更改存储时都会创建该对象)<代码>{}
不是单例。它会创建一个新对象。您需要将用户存储在store对象中并从中获取它。这就是为什么mapstatetops
将存储作为参数->来实际从中获取一些内容。您仍在创建一个新的用户对象constu={}
将在每次调用mapstatetops
时创建一个新的空对象