Skip to content

Commit 98ea6be

Browse files
coderpawzbenjycui
authored andcommitted
refactor: update react refs to use callback instead of string (#63)
1 parent db4cb71 commit 98ea6be

File tree

4 files changed

+53
-17
lines changed

4 files changed

+53
-17
lines changed

examples/nested.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,26 @@ const popupBorderStyle = {
3737
padding: 10,
3838
};
3939

40+
function saveRef(name, component) {
41+
this[name] = component;
42+
}
43+
4044
class Test extends React.Component {
45+
constructor(props) {
46+
super(props);
47+
48+
this.saveContainerRef = saveRef.bind(this, 'containerInstance');
49+
}
50+
4151
render() {
4252
const innerTrigger = (
4353
<div style={popupBorderStyle}>
44-
<div ref="container" />
54+
<div ref={this.saveContainerRef} />
4555
<Trigger
4656
popupPlacement="bottom"
4757
action={['click']}
4858
builtinPlacements={builtinPlacements}
49-
getPopupContainer={() => this.refs.container}
59+
getPopupContainer={() => this.containerInstance}
5060
popup={<div style={popupBorderStyle}>I am inner Trigger Popup</div>}
5161
>
5262
<span href="#" style={{ margin: 20 }}>clickToShowInnerTrigger</span>

src/Popup.js

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import Align from 'rc-align';
55
import Animate from 'rc-animate';
66
import PopupInner from './PopupInner';
77
import LazyRenderBox from './LazyRenderBox';
8+
import { saveRef } from './utils';
89

910
class Popup extends Component {
1011
static propTypes = {
@@ -21,6 +22,13 @@ class Popup extends Component {
2122
onMouseLeave: PropTypes.func,
2223
};
2324

25+
constructor(props) {
26+
super(props);
27+
28+
this.savePopupRef = saveRef.bind(this, 'popupInstance');
29+
this.saveAlignRef = saveRef.bind(this, 'alignInstance');
30+
}
31+
2432
componentDidMount() {
2533
this.rootNode = this.getPopupDomNode();
2634
}
@@ -38,7 +46,7 @@ class Popup extends Component {
3846
}
3947

4048
getPopupDomNode() {
41-
return ReactDOM.findDOMNode(this.refs.popup);
49+
return ReactDOM.findDOMNode(this.popupInstance);
4250
}
4351

4452
getTarget = () => {
@@ -69,7 +77,7 @@ class Popup extends Component {
6977
}
7078

7179
getPopupElement() {
72-
const props = this.props;
80+
const { savePopupRef, props } = this;
7381
const { align, style, visible, prefixCls, destroyPopupOnHide } = props;
7482
const className = this.getClassName(this.currentAlignClassName ||
7583
props.getClassNameFromAlign(align));
@@ -84,7 +92,7 @@ class Popup extends Component {
8492
const popupInnerProps = {
8593
className,
8694
prefixCls,
87-
ref: 'popup',
95+
ref: savePopupRef,
8896
onMouseEnter: props.onMouseEnter,
8997
onMouseLeave: props.onMouseLeave,
9098
style: newStyle,
@@ -99,7 +107,7 @@ class Popup extends Component {
99107
{visible ? (<Align
100108
target={this.getTarget}
101109
key="popup"
102-
ref={this.saveAlign}
110+
ref={this.saveAlignRef}
103111
monitorWindowResize
104112
align={align}
105113
onAlign={this.onAlign}
@@ -123,7 +131,7 @@ class Popup extends Component {
123131
<Align
124132
target={this.getTarget}
125133
key="popup"
126-
ref={this.saveAlign}
134+
ref={this.saveAlignRef}
127135
monitorWindowResize
128136
xVisible={visible}
129137
childrenProps={{ visible: 'xVisible' }}
@@ -181,10 +189,6 @@ class Popup extends Component {
181189
return maskElement;
182190
}
183191

184-
saveAlign = (align) => {
185-
this.alignInstance = align;
186-
}
187-
188192
render() {
189193
return (
190194
<div>

src/utils.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,7 @@ export function getPopupClassNameFromAlign(builtinPlacements, prefixCls, align)
2121
}
2222
return '';
2323
}
24+
25+
export function saveRef(name, component) {
26+
this[name] = component;
27+
}

tests/index.js

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import '../assets/index.less';
99
import Trigger from '../index';
1010
import './test.less';
1111
import async from 'async';
12+
import { saveRef } from '../src/utils';
1213

1314
const Simulate = TestUtils.Simulate;
1415
window.$ = $;
@@ -235,18 +236,24 @@ describe('rc-trigger', function main() {
235236

236237
it('nested action works', (done) => {
237238
class Test extends React.Component {
239+
constructor(props) {
240+
super(props);
241+
242+
this.saveClickTriggerRef = saveRef.bind(this, 'clickTriggerInstance');
243+
this.saveHoverTriggerRef = saveRef.bind(this, 'hoverTriggerInstance');
244+
}
238245
render() {
239246
return (
240247
<Trigger
241248
action={['click']}
242249
popupAlign={placementAlignMap.left}
243-
ref="clickTrigger"
250+
ref={this.saveClickTriggerRef}
244251
popup={<strong>click trigger</strong>}
245252
>
246253
<Trigger
247254
action={['hover']}
248255
popupAlign={placementAlignMap.left}
249-
ref="hoverTrigger"
256+
ref={this.saveHoverTriggerRef}
250257
popup={<strong>hover trigger</strong>}
251258
>
252259
<div className="target">trigger</div>
@@ -262,19 +269,19 @@ describe('rc-trigger', function main() {
262269
Simulate.mouseEnter(target);
263270
Simulate.click(target);
264271
async.series([timeout(200), (next) => {
265-
const clickPopupDomNode = trigger.refs.clickTrigger.getPopupDomNode();
266-
const hoverPopupDomNode = trigger.refs.hoverTrigger.getPopupDomNode();
272+
const clickPopupDomNode = trigger.clickTriggerInstance.getPopupDomNode();
273+
const hoverPopupDomNode = trigger.hoverTriggerInstance.getPopupDomNode();
267274
expect(clickPopupDomNode).to.be.ok();
268275
expect(hoverPopupDomNode).to.be.ok();
269276
Simulate.mouseLeave(target);
270277
next();
271278
}, timeout(200), (next) => {
272-
const hoverPopupDomNode = trigger.refs.hoverTrigger.getPopupDomNode();
279+
const hoverPopupDomNode = trigger.hoverTriggerInstance.getPopupDomNode();
273280
expect($(hoverPopupDomNode).css('display')).to.be('none');
274281
Simulate.click(target);
275282
next();
276283
}, timeout(200), (next) => {
277-
const clickPopupDomNode = trigger.refs.clickTrigger.getPopupDomNode();
284+
const clickPopupDomNode = trigger.clickTriggerInstance.getPopupDomNode();
278285
expect($(clickPopupDomNode).css('display')).to.be('none');
279286
next();
280287
}], done);
@@ -656,4 +663,15 @@ describe('rc-trigger', function main() {
656663
expect(popupNodeHeightOfOneWord).to.equal(popupNodeHeightOfSeveralWords);
657664
});
658665
});
666+
667+
describe('utils/saveRef', () => {
668+
const mock = {};
669+
const saveTestRef = saveRef.bind(mock, 'testInstance');
670+
671+
it('adds a property with the given name to context', () => {
672+
expect(mock.testInstance).to.be(undefined);
673+
saveTestRef('bar');
674+
expect(mock.testInstance).to.be('bar');
675+
});
676+
});
659677
});

0 commit comments

Comments
 (0)