gpt4 book ai didi

reactjs - 使用 React.cloneElement 和 render prop 将 ref 传递给类组件

转载 作者:行者123 更新时间:2023-12-03 13:38:59 45 4
gpt4 key购买 nike

我正在编写一个组件,根据其子级的ref(例如与该子级的ref相关的鼠标事件)处理一些内部状态
该组件使用 render-prop 将相关的 state 传递给它的子组件,并通过附加的 ref 渲染子组件React.cloneElement 实用程序。

问题是,当子组件是 class 组件时,由于某种原因 ref 不可用,并且我找不到将其呈现为的方法它是一个具有 function 类型的 React 元素对象(当然是在我克隆它之后)。

但是,如果子级只是一个 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 组件)时,它不起作用如上所述。

最佳答案

我遇到了几乎相同的问题。
我选择使用findDOMNodereact-dom,你可以看到完整的解决方案 in react-external-click

尽管警告指出:

findDOMNode is an escape hatch used to access the underlying DOM node. In most cases, use of this escape hatch is discouraged because it pierces the component abstraction.

findDOMNode only works on mounted components (that is, components that have been placed in the DOM). If you try to call this on a component that has not been mounted yet (like calling findDOMNode() in render() on a component that has yet to be created) an exception will be thrown.

findDOMNode cannot be used on functional components.

我认为这是应对这一特殊挑战的更好解决方案。
它让您对消费者“透明”,同时能够定位 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
}
}
}

关于reactjs - 使用 React.cloneElement 和 render prop 将 ref 传递给类组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50199328/

45 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com