我试图将组件的引用传递给另一个组件。自不推荐字符串引用。以来,我使用的是回调推荐。
所以我有一个类似的东西:
<One ref={c => this.one = c}/>
<Two one={this.one}/>问题是,每当我试图在Two中访问Two时,都会得到undefined。
我甚至在Two上试过这个
componentDidMount(){
setTimeout(()=>{
console.log(this.props.one);
},5000)
}问题似乎是,当支柱被创建时,ref还不存在,因为它是在One挂载后创建的。但我不知道如何“刷新”Two上的道具,以便将ref发送到挂载组件。
那么,向另一个组件传递引用的正确方式是什么呢?
编辑
一些用户建议将该逻辑封装在一个更高的组件中,这本身就会使这些其他子组件呈现出来。
这种方法的问题在于,您不能创建可重用的逻辑,您必须在这些封装组件中反复重复相同的逻辑。
假设您想要创建一个通用的<Form>组件,它将提交逻辑封装到您的存储、错误检查等。然后执行如下操作:
<Form>
<Input/>
<Input/>
<Input/>
<Input/>
<SubmitButton/>
</Form>在本例中,<Form>无法访问子实例(和方法),因为this.props.children不返回这些实例。它返回一些伪组件的列表。
那么,如何检查某个<Input/>是否检测到了验证错误,而不通过一个引用呢?
您必须使用验证逻辑将这些组件封装在另一个组件中。例如在<UserForm>中。但是由于每个表单是不同的,所以必须在<CategoryForm>、<GoupForm>等中复制相同的逻辑。这是非常低效率的,这就是为什么我希望将验证逻辑封装在<Form>中,并将<Input>组件的引用传递给<Form>。
发布于 2016-08-10 04:12:43
一般来说,“参考”功能是一个反模式的反应。它的存在是为了支持副作用驱动的开发,但是,如果可能的话,为了从编程的反应方式中获益,你应该尽量避免“推荐”。
至于你的特殊问题,把一个孩子交给它的兄弟姐妹是鸡对蛋的场景。ref回调是在安装子程序时触发的,而不是在呈现过程中触发的,这就是为什么您的示例无法工作。您可以尝试的一件事是将裁判推入状态,然后从状态读到另一个子节点。所以:
<One ref={c => !this.state.one && this.setState({ one: c })}/>
<Two one={this.state.one}/>注意:如果没有!this.state.one,这将导致无限循环。
下面是此工作的代码依赖示例(查看控制台以查看记录的兄弟关系引用):http://codepen.io/anon/pen/pbqvRA
发布于 2019-04-10 21:56:39
现在使用新参考api要简单得多(自从React 16起就可用了--这要归功于指出这一点的危机四伏)。
class MyComponent extends React.Component {
constructor (props) {
super(props);
this.oneRef = React.createRef();
}
render () {
return (
<React.Fragment>
<One ref={this.oneRef} />
<Two one={this.oneRef} />
</React.Fragment>
}
}
}您将在Two中使用如下所示的支柱:
this.props.one.current通过这种方法,有几点值得注意:
ref将是一个具有current属性的对象。该属性将是null ,直到元素/组件挂载为止。一旦它被挂载,它将是One的实例。一旦安装了<Two />,应该可以安全地引用它。
卸载<One />实例后,ref上的current属性返回为null。
发布于 2018-06-25 13:36:00
通常,如果需要传递对调用时可能没有设置的引用,则可以传递lambda:
<One ref={c => this.one = c}/>
<Two one={() => this.one}/>然后将其引用为
this.props.one()如果在调用它时设置了它,则会得到一个值。在此之前,您将得到undefined (假设它没有被初始化)。
值得注意的是,当它可用时,您不一定会重新呈现,我希望它在第一个呈现时是undefined。这是使用state保存引用确实可以处理的事情,但是您不会得到多于一次的重呈现。
鉴于所有这些,我建议将使用ref的任何代码移到One中的Two中,将其移到呈现One和Two的组件中,以避免这种策略以及@Carl的答案中的所有问题。
https://stackoverflow.com/questions/38864033
复制相似问题