【问题标题】:Cannot read property 'getBoundingClientRect' of null无法读取 null 的属性“getBoundingClientRect”
【发布时间】:2019-05-31 04:18:23
【问题描述】:

我收到此错误:Cannot read property 'getBoundingClientRect' of null。我使用这个函数getBoundingClientRect,因为在我的项目中我想要有以下效果:在一个元素被突出显示的那一刻,其余的有不同的样式。该消息显示函数handleScroll。我使用的组件是这样的

class QuestionListItem extends Component {
  constructor() {
    super();
    this.state = {
      isActive: false,
    };

    this.handleScroll = this.handleScroll.bind(this);
  }

  componentDidMount = () => {
    window.addEventListener('scroll', this.handleScroll);
    this.handleScroll();
  };

  handleScroll = () => {
    const { isActive } = this.state;
    const { top } = this.wrapRef.getBoundingClientRect();
    if (top > 60 && top < 400 && !isActive) {
      this.setState({ isActive: true });
    }
    if ((top <= 60 || top >= 400) && isActive) {
      this.setState({ isActive: false });
    }
  }

  setWrapRef = (ref) => {
    this.wrapRef = ref;
  }

  render() {
    const { isActive } = this.state;
    const { question } = this.props;
    return (
      <div
        className={`Test__questions-item--noactive ${isActive && 'Test__questions-item--active'}`}
        ref={this.setWrapRef}
      >
        <li key={question.id}>
          <p>
            {question.question}
          </p>
          <QuestionAnswerForm name={question.question} />
        </li>
      </div>
    );
  }
}

为什么会出现这样的错误?提前感谢您的帮助:)

【问题讨论】:

标签: reactjs


【解决方案1】:

我注意到你的代码,在那里你使用了带有 componentDidMount 的箭头函数。

应该是:

componentDidMount() {}

另外,如果你使用带有handleScroll的箭头函数,那么就不需要在构造函数中绑定,尝试删除它,然后修改handleScroll如下:

handleScroll = () => {
    const { isActive } = this.state;
    if (this.wrapRef) {
       const { top } = this.wrapRef.getBoundingClientRect();
       if (top > 60 && top < 400 && !isActive) {
          this.setState({ isActive: true });
       }
       if ((top <= 60 || top >= 400) && isActive) {
          this.setState({ isActive: false });
       }
    }
  }

还要在 componentDidMount 中的事件监听器之后删除函数调用 this.handleScroll(),因为它没有用。

【讨论】:

  • 没有错误,但是状态没有更新,样式没有改变。好像没有调用函数handleScroll
  • @Elder handleScroll 仅在当前组件中有滚动条时调用,我不知道样式但应该在具有溢出属性的 div 上固定高度,以便它具有滚动条分配给滚动事件监听器
  • 是的,它的作品。我添加 componentWillUnmount() { window.removeEventListener('scroll', this.handleScroll); ,一切都很好:)
  • @Elder,如果对您有帮助,请接受答案。
【解决方案2】:

我认为问题在于您没有为wrapRef 创建任何ref。正如错误所说,无法获得 null 的属性;所以wrapRef 本身是空的

class QuestionListItem extends Component {
  constructor() {
    super();
    this.state = {
      isActive: false,
    };

    this.handleScroll = this.handleScroll.bind(this);
  }

  componentDidMount = () => {
    window.addEventListener('scroll', this.handleScroll);
    this.handleScroll();
  };

  wrapRef=React.createRef();

  handleScroll = () => {
    const { isActive } = this.state;
    const { top } = this.wrapRef.current.style;
    if (top > 60 && top < 400 && !isActive) {
      this.setState({ isActive: true });
    }
    if ((top <= 60 || top >= 400) && isActive) {
      this.setState({ isActive: false });
    }
  }

  render() {
    const { isActive } = this.state;
    const { question } = this.props;
    return (
      <div
        className={`Test__questions-item--noactive ${isActive && 'Test__questions-item--active'}`}
        ref={this.wrapRef}
      >
        <li key={question.id}>
          <p>
            {question.question}
          </p>
          <QuestionAnswerForm name={question.question} />
        </li>
      </div>
    );
  }
}

【讨论】:

  • 我不明白我应该改变什么
  • 编辑了答案
  • 还要注意你的ref={this.wrapRef}div
猜你喜欢
  • 2020-08-08
  • 2021-02-27
  • 1970-01-01
  • 1970-01-01
  • 2021-03-02
  • 2021-04-17
  • 2017-08-03
  • 1970-01-01
  • 2023-03-10
相关资源
最近更新 更多