高阶组件总是重新渲染忽略shouldComponentUpdate

时间:2016-08-19 05:37:37

标签: reactjs

我有一个像这样的更高阶的组件

// higherOrderComponent.js
const HigherOrderComponent = Component => class extends React.Component {
  shouldComponentUpdate (nextProps, nextState) {
    return false
  }

  render () {
    return <Component {...this.props} />
  }
}

export default HigherOrderComponent

// myComponent.js
import HigherOrderComponent from './higherOrderComponent'

class MyComponent extends React.Component {
  render () {
    return <div>my component</div>
  }
}

export default HigherOrderComponent(MyComponent)

// parentComponent.js
import MyComponent from './myComponent'

class ParentComponent extends React.Component {
  render () {
    return <MyComponent />
  }
}

我明确地返回false但是组件总是被重新渲染。知道为什么吗?我最终希望在组件之间共享“shouldComponentUpdate”。如果高阶组件不起作用,我该如何实现呢?

4 个答案:

答案 0 :(得分:1)

因为您没有指定调用高阶组件的方式,所以我根据问题猜测了您如何使用它。

我的答案基于您正在调用高阶函数的假设,如

var MyHigherOrderFn = (HigherOrderComponent(Baar));

如果有人如何在return render中调用您的高阶函数(如下所示),则可以避免此问题。

<HigherOrderComponent prop1="Hello" child="Child" />

因为我不知道如何以上述方式调用你的函数(我甚至不确定它是否可能),我创建了HigherOrderComponent2,它具有不同的语法风格,可以调用,类似于{ {1}}

shouldComponentUpdate
<Parent prop1="val1">
    <Child>
</Parent>

答案 1 :(得分:1)

我修改了您的代码以创建代码段并且按预期工作,MyComponent.render仅在shouldComponentUpdate返回false时调用一次。

我的猜测是,不知何故,你正在使用未包装的MyComponent版本而不是包装的版本。你的构建环境可能有问题吗?

&#13;
&#13;
// higherOrderComponent.js
const HigherOrderComponent = Component => class extends React.Component {
  shouldComponentUpdate (nextProps, nextState) {
    return false;
  }

  render () {
    return <Component {...this.props} />
  }
}

class MyComponent extends React.Component {
  render () {
  	console.log('render');
    return <div>my component</div>
  }
}

const MyComponentHOC = HigherOrderComponent(MyComponent);

class ParentComponent extends React.Component {
  render () {
    return <MyComponentHOC />
  }
}

ReactDOM.render(<ParentComponent/>, document.getElementById('container'));
ReactDOM.render(<ParentComponent/>, document.getElementById('container'));
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>


<div id="container"></div>
&#13;
&#13;
&#13;

答案 2 :(得分:0)

它是关于反应组分的生命周期。当组件初始化时,它不会检查shouldComponentUpdate。只有在状态/道具改变时才会调用ShouldComponentUpdate。

FYI生命周期方法按顺序调用:

初始化组件时 getDefaultProps getInitialStage componentWillMount 给予 componentDidMount

组件状态发生变化时 shouldComponentUpdate componentWillUpdate 给予 componentDidUpdate

当组件更改道具时 componentWillReceiveProps shouldComponentUpdate componentWillUpdate 给予 componentDidUpdate

卸载组件时 componentWillUnmount

答案 3 :(得分:0)

您需要使用称为继承反转的不同类型的HOC模式来访问生命周期方法。由于您要覆盖shouldComponentUpdate,因此不要调用super,但需要在子类组件呈现方法中调用super.render()

试试这个......

const HigherOrderComponent = () => WrappedComponent =>
  class ShouldNotUpdate extends WrappedComponent {
    shouldComponentUpdate(nextProps) {
      return false
    }
    render() {
      return super.render()
    }
  }

使用currying是一种很好的做法,因为您可以在将来注释您的课程,如...

@HigherOrderComponent
class MyClass extends React.Component {
  render() {
    return <div>something</div>
  }
}

// or without annotations..

const MyNewClass = HigherOrderComponent()(MyClass)