[英]Access parent's Ref in child component on child mount
我具有以下父/子组件。 最初渲染Child组件后,我需要滚动到顶部。
import React, {Component} from 'react';
import Child from "./Child";
class Parent extends Component {
render() {
return (
<div>
<div ref={topDiv => {
this.topDiv = topDiv;
}}/>
<Child
topDiv={this.topDiv}
/>
</div>
);
}
}
export default Parent;
import React, {Component} from 'react';
class Child extends Component {
componentDidMount() {
this.scrollToTop();
}
// componentWillReceiveProps(nextProps, nextContext) {
// nextProps.topDiv.scrollIntoView();
// }
scrollToTop() {
this.props.topDiv.scrollIntoView();
}
render() {
return (
<div style={{height: '500rem'}}>
Long Child
</div>
);
}
}
export default Child;
使用此,我得到错误:
TypeError:无法读取未定义的属性“ scrollIntoView”
我认为这是因为调用componentDidMount
时,尚未收到道具,因此topDiv
为null / undefined。
如果我使用注释部分所示的componentWillReceiveProps
,则可以正常工作。 但我不能使用它,因为:
1.不推荐使用。
2.我认为每次收到道具时都会调用它。 因此,我想我需要保留一个变量以了解是否是第一次收到道具?
我不能使用componentDidUpdate
因为文档 显示 “ 初始渲染未调用此方法。 ”。
渲染组件后首次收到道具时该怎么办?
道具绝对应该在componentDidMount
可用。
看来这可能是由于React生命周期中有些混乱。
在父级中,大约在安装Child
的同时,在渲染器中提供ref回调。 根据React docs :
当组件安装时,React将使用DOM元素调用ref回调,而在卸载时使用null调用它。 保证在componentDidMount或componentDidUpdate触发之前,引用是最新的。
但是,子级的componentDidMount
将在其父级的componentDidMount
之前触发,因此,此保证并不意味着Parent
的this.topDiv
将在Child
调用componentDidMount
之前定义。 (而且,进一步考虑,它绝对不能保证在将其作为道具提供给Child
之前将其定义。)
在您父母的身边,您可以尝试类似
componentDidMount() {
this.setState({ divSet: true });
}
render() {
let child = null;
if (this.state.divSet) {
child = <Child topDiv={this.topDiv} />
}
return (
<div>
<div ref={topDiv => {
this.topDiv = topDiv;
}}/>
{child}
</div>
);
}
这将确保您的ref在Child
挂载之前被设置。 setState
专门用于在设置ref时强制父级重新呈现。
根据定义,您正在尝试做的事情是不可能的! 当你说
最初渲染Child组件后,我需要滚动到顶部。
你的意思是父母的右上角?
但是这里的关键细节是
您的孩子完成渲染后,您的父母还没有渲染! 没有顶部可以滚动到!
组件的生命周期
这是组件的典型生命周期流程
当涉及到亲子关系时
也是关于新添加的生命周期方法的一则小注释,它代替了componenWillRecieveProps
getDerivedStateFromProps(道具,状态)
在初始安装和后续更新上,都在调用render方法之前立即调用getDerivedStateFromProps。 它应该返回一个对象以更新状态,或者返回null则不更新任何内容。
因此,最好的选择是在您的组件componentDidMount中调用滚动顶部,您可以在其中访问其引用。
如果仍然确定要在子组件中执行此操作,则必须结合使用getDerivedStateFromProps和状态标记来检测是否已至少滚动到顶部一次。 总体上来说这可能有点高效和肮脏。
请在此处查看组件生命周期的凉爽流程图,以了解其清晰性!
将this.scrollToTop
绑定到constructor
类组件:
class Child extends Component {
constructor() {
this.scrollToTop = this.scrollToTop.bind(this);
}
...rest of your component code
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.