UNPKG

1.31 kBJavaScriptView Raw
1import React, {createElement} from 'react';
2import {findDOMNode, render} from 'react-dom';
3
4/**
5 * Wraps a component to add a "rerender" method
6 * @param ComposedComponent
7 * @param captureNode, whether the wrapper should capture this.node itself. Set to false if the component already has "node" property captured
8 * @returns {Rerenderer}
9 */
10export default function rerenderHOC(ComposedComponent, {captureNode} = {captureNode: true}) {
11 return class Rerenderer extends ComposedComponent {
12 _propsCache = {};
13
14 onRefUpdate = component => {
15 // eslint-disable-next-line react/no-find-dom-node
16 this.node = findDOMNode(component);
17 };
18
19 rerender(props = {}, callback) {
20 let container;
21
22 try {
23 container = this.node.parentNode;
24 } finally {
25 if (!container) {
26 throw new Error(`${this.constructor.name} component isn't mounted`);
27 }
28 }
29
30 this._propsCache = Object.assign({}, this.props, this._propsCache, props);
31
32 return render(createElement(this.constructor, this._propsCache), container, callback);
33 }
34
35 render() {
36 if (!captureNode) {
37 return super.render();
38 }
39
40 return (
41 <ComposedComponent
42 ref={this.onRefUpdate}
43 {...this.props}
44 />
45 );
46 }
47 };
48}