Reactjs shouldComponentUpdate vs functions

时间:2015-12-07 15:55:48

标签: javascript reactjs

为了提高性能,我正在尝试在我的一些组件上实现shouldComponentUpdate。我们以通常的方式进行 - 拥有不可变模型并进行参考比较。它在很大程度上起作用,但我一直想知道我是否正确处理道具中的功能。

基本上,我的问题是:在shouldComponentUpdate中,你通常用道具中的函数做什么?你是否忽略了他们altoghether,或者你试图以某种方式比较它们?

以下是一个例子:

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>
    }
});

假设我需要Inner组件来拥有shouldComponentUpdate(假设它被渲染很多次并且很难渲染)。你会如何实现它?我尝试了以下方法:

1)this.props.onClick === newProps.onClick - 如果继续传递相同的方法,则有效,但在本例中不起作用,因为该方法是内联创建的。

2)this.props.onClick.toString()=== newProps.onClick.toString() - 如果函数在闭包中没有任何陈旧的情况下工作 - 在这里不起作用,因为val在函数的闭包中。

3)正如Michael指出的那样,你可以忽略shouldComponentUpdate中的函数,但问题与2)相同。

所有这些方法都可以引入微妙的错误,是否有更简单的方法来做到这一点?我知道重写这个例子很容易,但是理想情况下我希望能够将shouldComponentUpdate行为提取到尽可能健壮的mixin中,而不是适应这些问题。

2 个答案:

答案 0 :(得分:1)

我不相信在你的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你可以使用(虽然我还没有尝试过)。祝你好运!

答案 1 :(得分:0)

快速的想法是遍历所有键,而typeOf是一个函数,然后不检查,如果不是 - &gt;然后检查。我怀疑第一级有很多道具孩子,所以不应该慢。

也可以使用下划线比较对象http://underscorejs.org/#isEqual,但是,我还没有检查