将引用传递给道具的正确方法是什么? [英] What's the proper way of passing a ref to a prop?

查看:51
本文介绍了将引用传递给道具的正确方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将组件的引用传递给另一个组件.由于字符串引用已被弃用我正在使用回调引用.

I'm trying to pass a ref of a component to another component. Since string refs are being deprecated I'm using callback refs.

所以我有类似的东西:

<One ref={c => this.one = c}/>
<Two one={this.one}/>

问题是,每当我尝试访问 Two 中的 this.props.one 时,都会得到 undefined .

The problem is that whenever I try to access this.props.one inside Two I get undefined.

我什至在 Two 上尝试过:

componentDidMount(){
    setTimeout(()=>{
        console.log(this.props.one);
    },5000)
}

问题似乎是当创建prop时,ref并不存在,因为一旦安装了 One 后就创建了ref.但我不知道该如何刷新" Two 上的道具以获取对已安装组件的引用.

It seems the problem is that when the prop is created, the ref doesn't exist yet since it's created once One is mounted. But I don't know how to "refresh" the props on Two to get the ref to the mounted component.

那么将ref传递到另一个组件的正确方法是什么?

So what's the proper way of passing a ref to another component?

修改

一些用户建议将该逻辑封装在一个更高的组件中,该组件本身将呈现其他子组件.

Some users have suggested to encapsulate that logic in a higher component, which in itself renders those other child components.

这种方法的问题在于,您不能创建可重用的逻辑,而必须在那些封装组件中一遍又一遍地重复相同的逻辑.

The problem with that approach is that you can't create reusable logic and you have to repeat the same logic over and over in those encapsulating components.

假设您要创建一个通用的< Form> 组件,该组件将提交逻辑封装到您的商店,错误检查等中.您可以执行以下操作:

Let's say you want to create a generic <Form> component which encapsulates the submit logic to your store, error checking, etc. And you do something like this:

<Form>
    <Input/>
    <Input/>
    <Input/>
    <Input/>
    <SubmitButton/> 
</Form>

在此示例中,< Form> 无法访问子代的实例(和方法),因为 this.props.children 不返回这些实例.它返回一些伪组件列表.

In this example <Form> can't access the instances (and methods) of the children since this.props.children doesn't return those instances. It returns some list of pseudo components.

那么您如何检查某个< Input/> 是否在未通过引用的情况下检测到验证错误?

So how can you check if a certain <Input/> has detected a validation error without passing a ref?

您必须使用验证逻辑将那些组件封装在另一个组件中.例如,在< UserForm> 中.但是由于每种形式都不相同,因此必须在< CategoryForm> < GoupForm> 等中复制相同的逻辑.这效率非常低下,这就是为什么我要将验证逻辑封装在< Form> 中,并将< Input> 组件的引用传递给< Form> .

You have to encapsulate those components in another component with the validation logic. For example in <UserForm>. But since each form is different the same logic has to be copied in <CategoryForm>, <GoupForm>, etc. This is terribly inefficient which is why I want to encapsulate the validation logic in <Form> and pass references of the <Input> components to <Form>.

推荐答案

通常,"ref"功能是React中的反模式.它可以实现副作用驱动的开发,但是为了从React编程方式中获得最大收益,您应该尽可能避免使用"refs".

In general the "ref" feature is an anti-pattern in React. It exists to enable side-effect driven development, however in order to benefit the most from the React way of programming you should try to avoid "refs" if possible.

对于您的特定问题,将孩子带给同伴的参考是鸡与蛋的关系.ref回调是在挂载子级时触发的,而不是在渲染期间触发的,这就是您的示例无法正常工作的原因.您可以尝试的一件事是将ref推入状态,然后从状态读入另一个子级.所以:

As for your particular issue, passing a child a ref to it's sibling is a chicken vs. egg scenario. The ref callback is fired when the child is mounted, not during render which is why your example doesn't work. One thing you can try is pushing the ref into state and then reading from state into the other child. So:

<One ref={c => !this.state.one && this.setState({ one: c })}/>
<Two one={this.state.one}/>

注意:没有!this.state.one ,这将导致无限循环.

Note: without the !this.state.one this will cause an infinite loop.

这是此工作的codepen示例(请在控制台上查看已记录的同级引用): http://codepen.io/anon/pen/pbqvRA

Here is a codepen example of this working (look at the console to see the sibling ref logged): http://codepen.io/anon/pen/pbqvRA

这篇关于将引用传递给道具的正确方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆