我正在编写一个处理一些内部的组件state
根据一个ref
它的子级(例如与该子级的引用相关的鼠标事件)。
该组件正在使用render-prop
传递相关部分state
给它的孩子,并渲染孩子ref
通过附加React.cloneElement
util.
问题是当孩子是class
组件,由于某种原因ref
不可用,我找不到渲染它的方法,因为它是一个类型为的反应元素对象function
(当然是在我克隆它之后)。
但如果孩子只是一个DOM
节点像div
例如,它正在按预期工作。
我的解决方法是检查孩子的类型,如果它是function
我将用我自己的元素包装克隆的元素div
,如果它只是一个 dom 节点,则按原样渲染。
然而,我不想用额外的东西包裹孩子div
因为我不想添加不必要的DOM
nodes.
这是一个基本的代码示例,为了简洁起见,删除了大部分代码:
父组件:
class Parent extends Component {
attachRef = node => {
this.ref = node;
}
render() {
const { render } = this.props;
const { someValue } = this.state;
const Child = render(someValue);
const WithRef = React.cloneElement(Child, {
ref: this.attachRef
});
if (typeof WithRef.type === 'string') { // node element
return WithRef;
}
else if (typeof WithRef.type === 'function') {
// this is a react element object.. not sure how to render it
// return ?
} else {
// need to find a way to render without a wrapping div
return (
<div ref={this.attachRef}>{Child}</div>
);
}
}
}
用法:
class App extends Component {
render() {
return (
<div>
<Parent render={someValue => <div> {someValue}</div>} />
<Parent render={someValue => <Menu someValue={someValue} />} />
</div>
);
}
}
当我像第一个例子一样渲染常规 DOM 节点时,它工作得很好,当我尝试渲染Menu
(这是一个class
组件)它不能像上面提到的那样工作。
我有几乎相同的问题。
我选择使用查找DOM节点 https://reactjs.org/docs/react-dom.html#finddomnode from react-dom
,你可以看到完整的解决方案在反应外部点击 https://github.com/sag1v/react-external-click/blob/master/src/components/ExternalClick.js.
尽管警告指出:
findDOMNode 是一个用于访问底层 DOM 节点的逃生舱口。
在大多数情况下,不鼓励使用此逃生舱口,因为它
穿透组件抽象。
findDOMNode 仅适用于已安装的组件(即,
已被放置在 DOM 中)。如果您尝试在组件上调用此方法
尚未安装(例如在 render() 中调用 findDOMNode()
在尚未创建的组件上)将出现异常
抛出。
findDOMNode 不能用于功能组件。
我认为这是应对这一特殊挑战的更好解决方案。
它让您对消费者“透明”,同时能够定位组件中的目标DOM
.
好的,就在这里,抓住参考:
componentDidMount() {
this.ref = findDOMNode(this);
// some logic ...
}
这就是我在没有自己的包装器的情况下使用渲染函数的方式:
render() {
const { children, render } = this.props;
const { clickedOutside } = this.state;
const renderingFunc = render || children;
if (typeof renderingFunc === 'function') {
return renderingFunc(clickedOutside);
} else {
return null
}
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)