gpt4 book ai didi

javascript - 通过 React.cloneElement 维护组件引用

转载 作者:数据小太阳 更新时间:2023-10-29 06:14:53 29 4
gpt4 key购买 nike

我一直在测试使用 React.cloneElement() 扩展组件的 children 可能存在的限制/危险。我发现的一种可能的危险是可能会覆盖 refkey 等 Prop 。

但是,根据 React 的 0.13 release candidate (早在 2015 年):

However, unlike JSX and cloneWithProps, it also preserves refs. This means that if you get a child with a ref on it, you won't accidentally steal it from your ancestor. You will get the same ref attached to your new element.

[...]

Note: React.cloneElement(child, { ref: 'newRef' }) DOES override the ref so it is still not possible for two parents to have a ref to the same child, unless you use callback-refs.

我写了一个small React application克隆被推送的子组件,在两个级别测试 refs 的有效性:

class ChildComponent extends React.Component{
constructor(props){
super(props);

this.onClick = this.onClick.bind(this);
this.extendsChildren = this.extendChildren(this);
}

onClick(e) {
e.preventDefault();

try{
alert(this._input.value);
}catch(e){
alert('ref broken :(');
}
}

extendChildren(){
return React.Children.map(this.props.children, child => {
return React.cloneElement(
child,
{
ref: ref => this._input = ref
}
);
});
}

render() {
return(
<div>
<button onClick={this.onClick}>
ChildComponent ref check
</button>
{this.extendChildren()}
</div>
);
}
}


class AncestorComponent extends React.Component{
constructor(props){
super(props);

this.onClick = this.onClick.bind(this);
}

onClick(e) {
e.preventDefault();

try{
alert(this._input.value);
}catch(e){
alert('ref broken :(');
}

}

render() {
return (
<div>
<p>
The expected behaviour is that I should be able to click on both Application and ChildComponent check buttons and have a reference to the input (poping an alert with the input's value).
</p>
<button onClick={this.onClick}>
Ancestor ref check
</button>
<ChildComponent>
<input ref={ref => this._input = ref} defaultValue="Hello World"/>
</ChildComponent>
</div>
);
}
}

但是,我的 ChildComponent 中的 cloningElements 覆盖了输入字段中 AncestorComponent 的 ref 属性,我希望 ref 属性与新的 一起被保留ref 我定义为 React.cloneElement 的一部分。

您可以通过运行 CodePen 来测试它.

有没有我做错了什么,或者这个功能从那以后就被放弃了吗?

最佳答案

根据 Dan Abramov 的 response ,覆盖引用,即使有回调,仍然会覆盖引用。您需要调用当前引用作为回调声明的一部分:

return React.Children.map(this.props.children, child =>
React.cloneElement(child, {
ref(node) {
// Keep your own reference
this._input = node;
// Call the original ref, if any
const {ref} = child;
if (typeof ref === 'function') {
ref(node);
}
}
)
);

关于javascript - 通过 React.cloneElement 维护组件引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41876702/

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