在以下代码中,我希望所有<p>
标签都包含&#34; data-mini-slug&#34;要将<input>
标签返回的属性。
以下代码在返回一个<p>
dom元素时有效。
如何保留dom结构,如何将所有嵌套<p data-mini-slug="hello">
元素转换为输入? React是否有内置的解决方案?
function hoc(WrappedComponent) {
return class Enhancer extends WrappedComponent {
render() {
const elementsTree = super.render();
let newProps = {};
if (elementsTree) {
const miniSlug = elementsTree.props['data-mini-slug']
if (elementsTree.type === "p" && miniSlug) {
newProps = { value: `New props is ${miniSlug}` }
const props = Object.assign({}, elementsTree.props, newProps)
return <input {...props} />
}
}
return elementsTree
}
}
}
class Example extends React.Component {
render() {
// return <p data-mini-slug="deepChild" data-new-value="Deep nested child" />
return (
<div>
<h1>Hoc dom element conversion</h1>
<p data-mini-slug="child" data-new-value="Surface child" />
<div>
<div>
<p data-mini-slug="deepChild" data-new-value="Deep nested child" />
</div>
</div>
</div>
)
}
}
export default hoc(Example)
答案 0 :(得分:2)
您可以通过让函数在克隆元素中调用自身来创建循环。
import React from 'react'
function iterateOverChildren(children) {
return React.Children.map(children, child => {
if (!React.isValidElement(child)) {
return child;
}
if (child.props.children) {
child = React.cloneElement(child, {
children: iterateOverChildren(child.props.children)
});
}
return alterChild(child);
});
}
function alterChild(child) {
let newProps = {};
const miniSlug = child.props['data-mini-slug']
if (child.type === "p" && miniSlug) {
newProps = { value: `New props is ${miniSlug}` }
const props = Object.assign({}, child.props, newProps)
child = <input {...props} />
}
return child
}
function hoc(WrappedComponent) {
return class Enhancer extends WrappedComponent {
render() {
const elementsTree = super.render();
return iterateOverChildren(elementsTree.props.children)
}
}
}
class Example extends React.Component {
render() {
// return <p data-mini-slug="deepChild" data-new-value="Deep nested child" />
return (
<div>
<h1>Hoc dom element conversion</h1>
<p data-mini-slug="child" data-new-value="Surface child" />
<div>
<div>
<p data-mini-slug="deepChild" data-new-value="Deep nested child" />
</div>
</div>
</div>
)
}
}
export default hoc(Example)
答案 1 :(得分:0)
React解决方案将创建一个组件,可以根据某些支柱提取p
或input
function Comp(props){
if(props.dataMiniSlug)
return <p/>
else
return <input/>
}
如果出于某种原因,您必须按照您尝试的方式修改DOM(虚拟),您可以使用React.Children API递归遍历儿童。
render() {
const rootNode = super.render();
return transform (rootNode)
}
transform(node) {
if(node.props.children){
return React.Children.map(element.props.children, transform)
}
if (node.type === "p" && node.props['data-mini-slug'] !== undefined) {
return <input { ...node.props, value: `New props is ${node.props['data-mini-slug']}`}/>
}
return node
}
我再强烈建议你重新考虑这整个方法,否则希望它有所帮助。