我有以下父/子组件。我需要在 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: Cannot read property 'scrollIntoView' of undefined
我认为这是因为调用componentDidMount
时,还没有收到props,所以topDiv
为null/undefined。
如果我使用 componentWillReceiveProps
如评论部分所示,它工作正常。但我不能使用它,因为:
1. 已弃用。
2.我觉得每次收到props都会调用。所以我想我需要保留一个变量以了解它是否是第一次收到 Prop ?
我不能使用 componentDidUpdate
因为 documentation说“初始渲染时不会调用此方法。”。
组件渲染后第一次收到 props 怎么办?
最佳答案
Prop 绝对应该在 componentDidMount
中可用。
这似乎可能源于 React 生命周期的一些困惑。
在您的父级中,您大约在安装 Child
的同时在渲染中提供 ref 回调。根据React docs :
React will call the ref callback with the DOM element when the component mounts, and call it with null when it unmounts. Refs are guaranteed to be up-to-date before componentDidMount or componentDidUpdate fires.
但是,子级的 componentDidMount
将在其父级的 componentDidMount
之前触发,因此此保证并不意味着 Parent
的 this.topDiv
将在 Child
调用 componentDidMount
之前定义。 (而且,进一步考虑,它绝对不能保证它会在作为 Prop 提供给 Child
之前被定义。)
在你的 parent 身上,你也许可以尝试类似的东西
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 时强制父级重新渲染。
关于javascript - 在子挂载的子组件中访问父的 Ref,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55485295/