Pie*_*ier 28 javascript reactjs
我正在尝试将组件的ref传递给另一个组件.由于字符串引用已被弃用,我正在使用回调引用.
所以我有类似的东西:
<One ref={c => this.one = c}/>
<Two one={this.one}/>
Run Code Online (Sandbox Code Playgroud)
问题是每当我尝试进入this.props.one内部时Two我都会得到undefined.
我甚至试过这个Two:
componentDidMount(){
setTimeout(()=>{
console.log(this.props.one);
},5000)
}
Run Code Online (Sandbox Code Playgroud)
似乎问题在于,当创建prop时,ref仍然不存在,因为它已经创建了一次One.但我不知道如何"刷新"道具Two以获得已安装组件的引用.
那么将ref传递给另一个组件的正确方法是什么?
编辑
一些用户建议将该逻辑封装在更高的组件中,该组件本身会呈现其他子组件.
这种方法的问题在于您无法创建可重用的逻辑,并且必须在这些封装组件中反复重复相同的逻辑.
假设您要创建一个通用<Form>组件,它将提交逻辑封装到您的商店,错误检查等.您可以这样做:
<Form>
<Input/>
<Input/>
<Input/>
<Input/>
<SubmitButton/>
</Form>
Run Code Online (Sandbox Code Playgroud)
在此示例<Form>中,无法访问子节点的实例(和方法),因为this.props.children不返回这些实例.它返回一些伪组件列表.
那么如何在<Input/>不通过ref的情况下检查某个是否检测到验证错误?
您必须使用验证逻辑将这些组件封装在另一个组件中.例如在<UserForm>.但是,由于各形式是不同的相同的逻辑必须被复制在<CategoryForm>,<GoupForm>等等,这是非常低效的这就是为什么我要封装在验证逻辑<Form>和传递的引用<Input>部件<Form>.
Car*_*rre 22
通常,"ref"功能是React中的反模式.它的存在是为了实现副作用驱动的开发,但是为了从React的编程方式中获得最大的好处,你应尽量避免使用"refs".
至于你的特殊问题,给孩子一个参考它的兄弟是一个鸡与蛋的情景.挂载子进程时会触发ref回调,而不是在渲染期间触发,这就是为什么示例不起作用的原因.你可以尝试的一件事是将ref推入状态,然后从状态读到另一个孩子.所以:
<One ref={c => !this.state.one && this.setState({ one: c })}/>
<Two one={this.state.one}/>
Run Code Online (Sandbox Code Playgroud)
注意:如果没有!this.state.one这将导致无限循环.
下面是这个工作的codepen示例(查看控制台以查看sibling ref记录):http://codepen.io/anon/pen/pbqvRA
kev*_*oat 10
现在,使用新的ref api(从React 16开始可用-感谢perilandmishap指出了这一点),这要简单得多。
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>
}
}
}
Run Code Online (Sandbox Code Playgroud)
您会Two像这样消耗道具:
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>
}
}
}
Run Code Online (Sandbox Code Playgroud)
这种方法的一些注意事项:
引用将是具有current属性的对象。该属性将null 一直持续到元素/组件被安装为止。挂载后,它将是的实例One。一旦安装,应该安全地引用它<Two />。
一旦<One />实例被卸载时,current在裁判回报是财产null。
一般来说,如果你需要传递一个在调用时可能没有设置的引用,你可以传递一个 lambda:
<One ref={c => this.one = c}/>
<Two one={() => this.one}/>
Run Code Online (Sandbox Code Playgroud)
然后将其引用为
this.props.one()
Run Code Online (Sandbox Code Playgroud)
如果在您调用它时已设置它,您将获得一个值。在此之前,你会得到undefined(假设它没有被初始化)。
值得注意的是,当它可用时你不一定会重新渲染,我希望它undefined在第一次渲染时出现。这是使用 state 来保存您的参考确实可以处理的事情,但您不会获得多次重新渲染。
鉴于这一切,我会建议任何代码用的是裁判的移动One中Two成被渲染组件One和Two,以避免所有这两种策略,和一个在@Carl斯维尔的答案的问题。
| 归档时间: |
|
| 查看次数: |
27813 次 |
| 最近记录: |