Merge pull request #3771 from matrix-org/t3chguy/ReactDOM.findDOMNode

stop using ReactDOM.findDOMNode in componentWillUnmount, use refs
pull/21833/head
Michael Telatynski 2019-12-23 17:16:47 +00:00 committed by GitHub
commit 1098fc939a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 13 deletions

View File

@ -25,7 +25,6 @@ import shouldHideEvent from '../../shouldHideEvent';
import React, {createRef} from 'react'; import React, {createRef} from 'react';
import createReactClass from 'create-react-class'; import createReactClass from 'create-react-class';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import classNames from 'classnames'; import classNames from 'classnames';
import { _t } from '../../languageHandler'; import { _t } from '../../languageHandler';
@ -440,7 +439,7 @@ module.exports = createReactClass({
componentDidUpdate: function() { componentDidUpdate: function() {
if (this._roomView.current) { if (this._roomView.current) {
const roomView = ReactDOM.findDOMNode(this._roomView.current); const roomView = this._roomView.current;
if (!roomView.ondrop) { if (!roomView.ondrop) {
roomView.addEventListener('drop', this.onDrop); roomView.addEventListener('drop', this.onDrop);
roomView.addEventListener('dragover', this.onDragOver); roomView.addEventListener('dragover', this.onDragOver);
@ -484,7 +483,7 @@ module.exports = createReactClass({
// is really just for hygiene - we're going to be // is really just for hygiene - we're going to be
// deleted anyway, so it doesn't matter if the event listeners // deleted anyway, so it doesn't matter if the event listeners
// don't get cleaned up. // don't get cleaned up.
const roomView = ReactDOM.findDOMNode(this._roomView.current); const roomView = this._roomView.current;
roomView.removeEventListener('drop', this.onDrop); roomView.removeEventListener('drop', this.onDrop);
roomView.removeEventListener('dragover', this.onDragOver); roomView.removeEventListener('dragover', this.onDragOver);
roomView.removeEventListener('dragleave', this.onDragLeaveOrEnd); roomView.removeEventListener('dragleave', this.onDragLeaveOrEnd);

View File

@ -38,6 +38,12 @@ module.exports = createReactClass({
// XXX resizeMethod not actually used. // XXX resizeMethod not actually used.
resizeMethod: PropTypes.string, resizeMethod: PropTypes.string,
defaultToInitialLetter: PropTypes.bool, // true to add default url defaultToInitialLetter: PropTypes.bool, // true to add default url
inputRef: PropTypes.oneOfType([
// Either a function
PropTypes.func,
// Or the instance of a DOM native element
PropTypes.shape({ current: PropTypes.instanceOf(Element) }),
]),
}, },
statics: { statics: {
@ -148,7 +154,7 @@ module.exports = createReactClass({
const { const {
name, idName, title, url, urls, width, height, resizeMethod, name, idName, title, url, urls, width, height, resizeMethod,
defaultToInitialLetter, onClick, defaultToInitialLetter, onClick, inputRef,
...otherProps ...otherProps
} = this.props; } = this.props;
@ -171,7 +177,7 @@ module.exports = createReactClass({
if (onClick != null) { if (onClick != null) {
return ( return (
<AccessibleButton element='span' className="mx_BaseAvatar" <AccessibleButton element='span' className="mx_BaseAvatar"
onClick={onClick} {...otherProps} onClick={onClick} inputRef={inputRef} {...otherProps}
> >
{ textNode } { textNode }
{ imgNode } { imgNode }
@ -179,7 +185,7 @@ module.exports = createReactClass({
); );
} else { } else {
return ( return (
<span className="mx_BaseAvatar" {...otherProps}> <span className="mx_BaseAvatar" ref={inputRef} {...otherProps}>
{ textNode } { textNode }
{ imgNode } { imgNode }
</span> </span>
@ -188,21 +194,26 @@ module.exports = createReactClass({
} }
if (onClick != null) { if (onClick != null) {
return ( return (
<AccessibleButton className="mx_BaseAvatar mx_BaseAvatar_image" <AccessibleButton
className="mx_BaseAvatar mx_BaseAvatar_image"
element='img' element='img'
src={imageUrl} src={imageUrl}
onClick={onClick} onClick={onClick}
onError={this.onError} onError={this.onError}
width={width} height={height} width={width} height={height}
title={title} alt="" title={title} alt=""
inputRef={inputRef}
{...otherProps} /> {...otherProps} />
); );
} else { } else {
return ( return (
<img className="mx_BaseAvatar mx_BaseAvatar_image" src={imageUrl} <img
className="mx_BaseAvatar mx_BaseAvatar_image"
src={imageUrl}
onError={this.onError} onError={this.onError}
width={width} height={height} width={width} height={height}
title={title} alt="" title={title} alt=""
ref={inputRef}
{...otherProps} /> {...otherProps} />
); );
} }

View File

@ -14,8 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import React from 'react'; import React, {createRef} from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import createReactClass from 'create-react-class'; import createReactClass from 'create-react-class';
@ -90,6 +89,10 @@ module.exports = createReactClass({
}; };
}, },
UNSAFE_componentWillMount: function() {
this._avatar = createRef();
},
componentWillUnmount: function() { componentWillUnmount: function() {
// before we remove the rr, store its location in the map, so that if // before we remove the rr, store its location in the map, so that if
// it reappears, it can be animated from the right place. // it reappears, it can be animated from the right place.
@ -105,7 +108,7 @@ module.exports = createReactClass({
return; return;
} }
const avatarNode = ReactDOM.findDOMNode(this); const avatarNode = this._avatar.current;
rrInfo.top = avatarNode.offsetTop; rrInfo.top = avatarNode.offsetTop;
rrInfo.left = avatarNode.offsetLeft; rrInfo.left = avatarNode.offsetLeft;
rrInfo.parent = avatarNode.offsetParent; rrInfo.parent = avatarNode.offsetParent;
@ -125,7 +128,7 @@ module.exports = createReactClass({
oldTop = oldInfo.top + oldInfo.parent.getBoundingClientRect().top; oldTop = oldInfo.top + oldInfo.parent.getBoundingClientRect().top;
} }
const newElement = ReactDOM.findDOMNode(this); const newElement = this._avatar.current;
let startTopOffset; let startTopOffset;
if (!newElement.offsetParent) { if (!newElement.offsetParent) {
// this seems to happen sometimes for reasons I don't understand // this seems to happen sometimes for reasons I don't understand
@ -175,7 +178,7 @@ module.exports = createReactClass({
render: function() { render: function() {
const MemberAvatar = sdk.getComponent('avatars.MemberAvatar'); const MemberAvatar = sdk.getComponent('avatars.MemberAvatar');
if (this.state.suppressDisplay) { if (this.state.suppressDisplay) {
return <div />; return <div ref={this._avatar} />;
} }
const style = { const style = {
@ -215,6 +218,7 @@ module.exports = createReactClass({
style={style} style={style}
title={title} title={title}
onClick={this.props.onClick} onClick={this.props.onClick}
inputRef={this._avatar}
/> />
</Velociraptor> </Velociraptor>
); );