reactjs - 如何获得子级无状态功能组件的高度?

标签 reactjs components stateless refs

我试图获取无状态子组件的高度,以便我能够在父类中使用其高度,但出现以下错误:不变违规:无状态函数组件不能有引用文献。

简化的代码

父类

class App extends React.Component {
  componentDidMount() {
    console.log(this.header);
  }
  render() {
    return (
      <Child ref={component => this.header = component} />
    )
  }
}

子项

const Child = () => (
  <header ref="header">
    Some text  
  </header>
)

有办法做到这一点吗?

这里是 a Codepen with the error 的链接.

更新:

实际代码/上下文

所以我目前有一个 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>
)

在某些情况下,我想向此标题添加逻辑以使其具有动画效果(例如,在用户滚动时的主页上,我将标题动画化为当用户滚动经过某个点时固定标题 - 粘性标题,如果你愿意的话)。

我之前完成此操作的方法是为具有特定功能(如上所述)的 header 和一个不具有特定功能的 header 创建一个单独的类。但为了保持代码干燥,我将 header 分离出来,使其成为其自己的功能性无状态组件,并希望将其包装在类中,从而赋予其粘性 header 功能。

这是该类:

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>
        )
    }
}

这就是这个特定问题的背景 - 我希望这能让事情变得更加清晰。

P.很抱歉缺乏上下文,我想答案会比看起来更直接!

最佳答案

好的,首先感谢大家的回复 - 非常感谢!

我开始按照Win的建议实现react-waypoints,尽管很明显我需要多修改我的代码才能使其工作,所以我想我应该有最后一个尝试使用 refs 进行搜索并找到替代解决方案。

我正在寻找的答案实际上很简单,来自以下Github issue thread通过 mnpenner .

解决方案

因为 React 不允许对无状态功能组件进行引用,所以您可以将功能组件包装在包装器中,同时为包装器提供自己的 ref,如下所示:

  render() {
    return (
      <div ref={el => {this.childWrap = el;}}>
        <Child />
      </div>
    )
  }

然后,您可以通过定位包装器来访问组件的高度:

  componentDidMount() {
        if(this.childWrap && this.childWrap.firstChild) {
        let childHeight = this.childWrap.offsetHeight;
                console.log(childHeight);
    }
  }

虽然这可能不是最优雅的解决方案,但它确实暂时解决了我的问题。

这里是a Codepen以供引用。

关于reactjs - 如何获得子级无状态功能组件的高度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45525713/

相关文章:

java - 无状态 bean 的行为类似于有状态 session bean - 为什么?

javascript - 如何要求无状态功能组件(未知模块_createWrapper?)

用于故障转移配置和架构的 Java JAX-WS 多个 Web 服务

javascript - 从组件更新路由模型

javascript - 检索 firebase 数据库的内容

javascript - 为什么 TypeError : Cannot read property '0' of undefined?

reactjs - 如何从扫描的二维码中检索数据?

javascript - 无法绑定(bind) ngModel,因为它不是 "Component"的属性

reactjs - react : best way to inject Component in dynamically loaded HTML?

reactjs - 如何修复 "net::ERR_CONTENT_DECODING_FAILED 200"