【发布时间】:2018-05-06 11:46:44
【问题描述】:
我正在编写一个组件,根据它的孩子的 ref 处理一些内部 state(例如,与该孩子的 ref 相关的鼠标事件)。
该组件使用render-prop 将state 的相关部分传递给它的孩子,并通过React.cloneElement 实用程序附加ref 渲染孩子。
问题是当孩子是class 组件时,由于某种原因ref 不可用,我找不到渲染它的方法,因为它是一个具有@ 类型的反应元素对象987654329@(当然是在我克隆它之后)。
但如果子节点只是一个DOM 节点,例如div,它会按预期工作。
我的解决方法是检查子节点的类型,如果它是function 的类型,我将用我自己的div 包装克隆的元素,如果它只是一个 dom 节点,则按原样渲染.
但是,我不想用额外的div 包裹孩子,因为我不想添加不必要的DOM 节点。
这是一个基本代码示例,为简洁起见删除了大部分代码:
父组件:
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 组件)时,它不会像上面提到的那样工作。
【问题讨论】:
-
Menu 是 SFC(功能组件)吗,您介意分享您的 Menu 组件吗?
-
我对 SFC 没有任何问题,因为它们将返回
DOM节点。Menu实际上可以是任何东西,我真的不知道,因为我的组件将是某种库。在示例中,Menu是一个class组件,正如我所提到的,这就是事情进展的地方。 -
需要注意的是 ref 不能用于指向功能组件,因为它没有实例。
-
从上面的 sn-ps 来看,除了创建
this.ref引用之外,很难判断 ref 是如何实际使用的,您能否更具体地说明您的意思ref is not available?
标签: reactjs ecmascript-6 ref clone-element