A7D*_*7DC 4 components stateless refs reactjs
我正在尝试获取无状态子组件的高度,以便我能够在父类中使用它的高度,但是我收到以下错误: Invariant Violation: Stateless function components cannot have refs.
class App extends React.Component {
componentDidMount() {
console.log(this.header);
}
render() {
return (
<Child ref={component => this.header = component} />
)
}
}
Run Code Online (Sandbox Code Playgroud)
const Child = () => (
<header ref="header">
Some text
</header>
)
Run Code Online (Sandbox Code Playgroud)
有没有办法做到这一点?
这是一个带错误的Codepen链接.
更新:
所以我目前有一个Header组件,看起来像这样:
export const Header = ({dateDetailsButton, title, logo, backButton, signUpButton, inboxButton, header}) => (
<header header className="flex flex-row tc pa3 bb b--light-gray relative min-h-35 max-h-35">
{signUpButton ? <Link to="/edit-profile-contact" href="#" className="flex z-2"><AddUser /></Link> : null }
{backButton ? <BackButton className="flex z-2" /> : null }
<h1 className={logo ? "w-100 tc dark-gray lh-solid f4 fw5 tk-reklame-script lh-solid ma0" : "w-100 tc dark-gray lh-solid f4 fw4 absolute left-0 right-0 top-0 bottom-0 maa h1-5 z-0"}>{title}</h1>
{dateDetailsButton ? <Link to="/date-details" className="absolute link dark-gray right-1 top-0 bottom-0 maa h1-5 z-2">Details</Link> : null }
{inboxButton ? <Link to="/inbox" href="#" className="flex mla z-2"><SpeechBubble /></Link> : null}
</header>
)
Run Code Online (Sandbox Code Playgroud)
在某些情况下,我想在此Header中添加逻辑以对其进行动画处理(例如,在用户滚动时在主页上,当我们滚动超过某个点时,我正在设置Header以使其成为固定的 - 如果您愿意,则为粘性标题).
我之前做过这种方式的方法是为一个具有特定功能的Header(如上所述)和一个没有的Header单独创建一个Class.但是为了保持我的代码DRY,我将Header分离为它自己的功能无状态组件,并将视图封装在Class中,为其提供了粘性标头功能.
这是类的:
export default class FeedHeader extends React.Component {
constructor(props) {
super(props);
this.handleScroll = this.handleScroll.bind(this);
this.state = {
scrolledPastHeader: null,
from: 0,
to: 1,
}
}
componentDidMount() {
window.addEventListener('scroll', this.handleScroll);
this.setState({navHeight: this.navHeight.offsetHeight});
}
componentWillUnmount() {
window.removeEventListener('scroll', this.handleScroll);
}
handleScroll(e) {
const { navHeight, scrolledPastHeader } = this.state;
const wy = document.body.scrollTop;
if (wy < navHeight) this.setState({scrolledPastHeader: null})
else if (wy > navHeight && wy < 100) {
this.setState({scrolledPastHeader: false})
}
else this.setState({scrolledPastHeader: true})
}
getMotionProps() {
const { scrolledPastHeader } = this.state;
return scrolledPastHeader === false ?
{
style: {
value: this.state.from
}
}
: {
style: {
value: spring(this.state.to)
}
}
}
render() {
const { brand, blurb } = this.props;
const { scrolledPastHeader } = this.state;
return (
<Motion {...this.getMotionProps()}>
{({value}) => {
return (
<Header ref="child" title={this.props.title} backButton={false} signUpButton inboxButton logo/>
);
}}
</Motion>
)
}
}
Run Code Online (Sandbox Code Playgroud)
所以这是这个特定问题的背景 - 我希望这会让事情变得更加清晰.
对于缺乏背景感到抱歉,我想象答案会比看起来更直接!
好的,首先,感谢大家的回复 - 非常感谢!
我开始react-waypoints按照Win的推荐实现,虽然很明显我需要修改我的代码以使其工作,所以我想我最后一次搜索试图找到一个替代解决方案使用refs.
我一直在寻找的答案实际上是相当简单的,并从以下来Github的问题线程通过mnpenner.
因为React不允许对无状态功能组件进行引用,所以你可以将功能组件包装在包装器中,同时给它自己的包装器ref,如下所示:
render() {
return (
<div ref={el => {this.childWrap = el;}}>
<Child />
</div>
)
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以通过定位包装器来访问组件的高度:
componentDidMount() {
if(this.childWrap && this.childWrap.firstChild) {
let childHeight = this.childWrap.offsetHeight;
console.log(childHeight);
}
}
Run Code Online (Sandbox Code Playgroud)
虽然这可能不是最优雅的解决方案,但它确实解决了我的问题.
这是Codepen供参考.
| 归档时间: |
|
| 查看次数: |
2685 次 |
| 最近记录: |