Open
Description
i'm having a problem w/ replacing JSX nodes within render props:
input:
const MyController = (props) => (
<Controller
render={() => (
<div id="inner" />
)}
/>
)
expected output:
const MyController = (props) => (
<Controller
render={() => (
<div id="outer">
<div id="inner" />
</div>
)}
/>
)
v0.11.0 actual output:
const MyController = (props) => (
<Controller
render={() => (
(<div id="inner" />)
)}
/>
)
v0.15.0 actual output:
[input was unmodified]
codemod:
module.exports = function (file, api) {
const j = api.jscodeshift;
const root = j(file.source);
// Find all JSX elements with the name 'Controller'
const controllerPaths = root.findJSXElements("Controller");
// Process the found JSX elements
controllerPaths.forEach((path) => {
const renderAttribute = path.node.openingElement.attributes.find(
(attr) => attr.name.name === "render"
);
if (
renderAttribute &&
renderAttribute.value.type === "JSXExpressionContainer" &&
renderAttribute.value.expression.type === "ArrowFunctionExpression"
) {
// Find the first JSXElement within the ArrowFunctionExpression
const renderFunctionBodyNode = renderAttribute.value.expression.body;
if (renderFunctionBodyNode) {
const idAttribute = j.jsxAttribute(
j.jsxIdentifier("id"),
j.jsxExpressionContainer(j.identifier("outer"))
);
// Create a new JSXElement with div as its opening element
const wrappedRenderFunctionBodyNode = j.jsxElement(
j.jsxOpeningElement(j.jsxIdentifier("div"), [idAttribute]),
j.jsxClosingElement(j.jsxIdentifier("div")),
[renderFunctionBodyNode]
);
// Replace the existing JSXElement with the new one
const renderFunctionBodyPaths = j(renderFunctionBodyNode);
const renderFunctionBodyPath = renderFunctionBodyPaths.get(0);
renderFunctionBodyPath.replace(wrappedRenderFunctionBodyNode)
}
}
});
return root.toSource();
};
is the codemod doing something wrong or is this a bug?
Metadata
Assignees
Labels
No labels