出于性能考虑,我正在尝试在某些组件上实现 shouldComponentUpdate。我们按照通常的方式来做——有一个不可变的模型并进行引用比较。它在大多数情况下都有效,但我一直想知道我是否正确处理 props 中的函数。
本质上,我的问题是:在 shouldComponentUpdate 中,您通常如何处理 props 中的函数?您是否完全忽略它们,还是尝试以某种方式比较它们?
这是一个例子:
var Inner = React.createClass({
shouldComponentUpdate(newProps){
return ???
},
render(){
return <div onClick={this.props.onClick} />;
}
});
var Outer = React.createClass({
getInitialState(){ return {value: 0}; },
render(){
var val = this.state.value;
return <div>
<span>{val}</span>
<Inner onClick={() => { this.setState({value: val + 1}) }} />
</div>
}
});
假设我需要内部组件有shouldComponentUpdate(假设它被渲染了很多次并且很难渲染)。你会如何实现它?我尝试了以下方法:
1) this.props.onClick === newProps.onClick - 如果您继续传递相同的方法,则有效,但在本例中不起作用,因为该方法是内联创建的。
2) this.props.onClick.toString() === newProps.onClick.toString() - 如果函数在闭包中没有任何过时的内容,则可以工作 - 在这里不起作用,因为 val
位于函数的闭包中。
3) 正如 Michael 指出的,您可以忽略 shouldComponentUpdate 中的函数,其问题与 2) 相同。
所有这些方法都有可能引入微妙的错误,是否有更简单的方法来做到这一点?我知道重写这个示例很容易工作,但理想情况下,我希望能够将 shouldComponentUpdate 行为提取到尽可能健壮的 mixin 中,而不是导致这些问题。
最佳答案
我不相信跳过 shouldComponentUpdate
中的函数真的是可取的,但承认有时这是不可避免的。
首先,关于内联方法的第一点。当涉及到安全有效地重新渲染组件时,这总是会给您带来困难,因此我建议尽可能不要使用内联方法。您的示例可以实现与如下编写的相同的效果:
class Inner extends React.PureComponent {
// PureComponent performs the shallow equal check
render(){
return <div onClick={this.props.onClick} />;
}
};
class Outer extends React.Component {
constructor(props) {
this.state = { value: 0 };
}
increment = () => {
this.setState({ value: this.state.value + 1 });
}
render() {
return (<div>
<span>{val}</span>
<Inner onClick={this.increment} />
</div>);
}
};
如果您已经用尽了此选项,并且它看起来不适用于您所拥有的用例,那么您当然可以编写自定义 shouldComponentUpdate
来跳过您的函数,我认为这将是最好的解决方案。只要确保每次不会出现令人讨厌的意外即可;如果您的函数具有在组件生命周期中发生变化的依赖项,请重新考虑您的方法,或者将这些依赖项作为常规 props
传递(这将触发更新)(如果它们还没有)。
这是一个helpful package你可以使用(虽然我还没有尝试过)。祝你好运!
关于javascript - Reactjs shouldComponentUpdate 与函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34137788/