mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Add findDOMNode transform
This commit is contained in:
@@ -11,6 +11,17 @@ APIs.
|
||||
* Use the `-d` option for a dry-run and use `-p` to print the output
|
||||
for comparison
|
||||
|
||||
### Included Scripts
|
||||
|
||||
`findDOMNode.js` updates `this.getDOMNode()` or `this.refs.foo.getDOMNode()`
|
||||
calls inside of `React.createClass` components to `React.findDOMNode(foo)`. Note
|
||||
that it will only look at code inside of `React.createClass` calls and only
|
||||
update calls on the component instance or its refs. You can use this script to
|
||||
update most calls to `getDOMNode` and then manually go through the remaining
|
||||
calls.
|
||||
|
||||
* `react-codemod findDOMNode <file>`
|
||||
|
||||
### Recast Options
|
||||
|
||||
Options to [recast](https://github.com/benjamn/recast)'s printer can be provided
|
||||
|
||||
@@ -34,6 +34,9 @@ function test(transformName, testFileName, options) {
|
||||
|
||||
describe('Transform Tests', () => {
|
||||
|
||||
it('transforms the "findDOMNode" tests correctly', () => {
|
||||
test('findDOMNode', 'findDOMNode-test');
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
'use strict';
|
||||
|
||||
var React = require('React');
|
||||
|
||||
var Composer = React.createClass({
|
||||
componentWillReceiveProps: function(nextProps) {
|
||||
this.getDOMNode();
|
||||
return foo(this.refs.input.getDOMNode());
|
||||
},
|
||||
|
||||
foo: function() {
|
||||
var ref = 'foo';
|
||||
var element = this.refs[ref];
|
||||
var domNode = element.getDOMNode();
|
||||
},
|
||||
|
||||
bar: function() {
|
||||
var thing = this.refs.foo;
|
||||
thing.getDOMNode();
|
||||
},
|
||||
|
||||
foobar: function() {
|
||||
passThisOn(this.refs.main.refs.list.getDOMNode());
|
||||
}
|
||||
});
|
||||
|
||||
var SomeDialog = React.createClass({
|
||||
render: function() {
|
||||
call(this.refs.SomeThing);
|
||||
return (
|
||||
<div />
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,34 @@
|
||||
'use strict';
|
||||
|
||||
var React = require('React');
|
||||
|
||||
var Composer = React.createClass({
|
||||
componentWillReceiveProps: function(nextProps) {
|
||||
React.findDOMNode(this);
|
||||
return foo(React.findDOMNode(this.refs.input));
|
||||
},
|
||||
|
||||
foo: function() {
|
||||
var ref = 'foo';
|
||||
var element = this.refs[ref];
|
||||
var domNode = React.findDOMNode(element);
|
||||
},
|
||||
|
||||
bar: function() {
|
||||
var thing = this.refs.foo;
|
||||
React.findDOMNode(thing);
|
||||
},
|
||||
|
||||
foobar: function() {
|
||||
passThisOn(React.findDOMNode(this.refs.main.refs.list));
|
||||
}
|
||||
});
|
||||
|
||||
var SomeDialog = React.createClass({
|
||||
render: function() {
|
||||
call(this.refs.SomeThing);
|
||||
return (
|
||||
<div />
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,135 @@
|
||||
/*eslint-disable no-comma-dangle*/
|
||||
|
||||
'use strict';
|
||||
|
||||
function getDOMNodeToFindDOMNode(file, api, options) {
|
||||
const j = api.jscodeshift;
|
||||
|
||||
require('./utils/array-polyfills');
|
||||
const ReactUtils = require('./utils/ReactUtils')(j);
|
||||
|
||||
const printOptions = options.printOptions || {quote: 'single'};
|
||||
const root = j(file.source);
|
||||
|
||||
const createReactFindDOMNodeCall = arg => j.callExpression(
|
||||
j.memberExpression(
|
||||
j.identifier('React'),
|
||||
j.identifier('findDOMNode'),
|
||||
false
|
||||
),
|
||||
[arg]
|
||||
);
|
||||
|
||||
const updateRefCall = (path, refName) => {
|
||||
j(path)
|
||||
.find(j.CallExpression, {
|
||||
callee: {
|
||||
object: {
|
||||
type: 'Identifier',
|
||||
name: refName,
|
||||
},
|
||||
property: {
|
||||
type: 'Identifier',
|
||||
name: 'getDOMNode',
|
||||
},
|
||||
},
|
||||
})
|
||||
.forEach(callPath => j(callPath).replaceWith(
|
||||
createReactFindDOMNodeCall(j.identifier(refName))
|
||||
));
|
||||
};
|
||||
|
||||
const updateToFindDOMNode = classPath => {
|
||||
var sum = 0;
|
||||
|
||||
// this.getDOMNode()
|
||||
sum += j(classPath)
|
||||
.find(j.CallExpression, {
|
||||
callee: {
|
||||
object: {
|
||||
type: 'ThisExpression',
|
||||
},
|
||||
property: {
|
||||
type: 'Identifier',
|
||||
name: 'getDOMNode',
|
||||
},
|
||||
},
|
||||
})
|
||||
.forEach(path => j(path).replaceWith(
|
||||
createReactFindDOMNodeCall(j.thisExpression())
|
||||
))
|
||||
.size();
|
||||
|
||||
// this.refs.xxx.getDOMNode() or this.refs.xxx.refs.yyy.getDOMNode()
|
||||
sum += j(classPath)
|
||||
.find(j.MemberExpression, {
|
||||
object: {
|
||||
type: 'MemberExpression',
|
||||
object: {
|
||||
type: 'MemberExpression',
|
||||
object: {
|
||||
type: 'ThisExpression',
|
||||
},
|
||||
property: {
|
||||
type: 'Identifier',
|
||||
name: 'refs',
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
.closest(j.CallExpression)
|
||||
.filter(path => (
|
||||
path.value.callee.property &&
|
||||
path.value.callee.property.type === 'Identifier' &&
|
||||
path.value.callee.property.name === 'getDOMNode'
|
||||
))
|
||||
.forEach(path => j(path).replaceWith(
|
||||
createReactFindDOMNodeCall(path.value.callee.object)
|
||||
))
|
||||
.size();
|
||||
|
||||
// someVariable.getDOMNode() wherre `someVariable = this.refs.xxx`
|
||||
sum += j(classPath)
|
||||
.findVariableDeclarators()
|
||||
.filter(path => {
|
||||
const init = path.value.init;
|
||||
const value = init && init.object;
|
||||
return (
|
||||
value &&
|
||||
value.type === 'MemberExpression' &&
|
||||
value.object &&
|
||||
value.object.type === 'ThisExpression' &&
|
||||
value.property &&
|
||||
value.property.type === 'Identifier' &&
|
||||
value.property.name === 'refs' &&
|
||||
init.property &&
|
||||
init.property.type === 'Identifier'
|
||||
);
|
||||
})
|
||||
.forEach(path => j(path)
|
||||
.closest(j.FunctionExpression)
|
||||
.forEach(fnPath => updateRefCall(fnPath, path.value.id.name))
|
||||
)
|
||||
.size();
|
||||
|
||||
return sum > 0;
|
||||
};
|
||||
|
||||
if (
|
||||
options['no-explicit-require'] ||
|
||||
ReactUtils.hasReact(root)
|
||||
) {
|
||||
const didTransform = ReactUtils
|
||||
.findReactCreateClass(root)
|
||||
.filter(updateToFindDOMNode)
|
||||
.size() > 0;
|
||||
|
||||
if (didTransform) {
|
||||
return root.toSource(printOptions) + '\n';
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
module.exports = getDOMNodeToFindDOMNode;
|
||||
Reference in New Issue
Block a user