React - 获取包装 class 组件的引用

React - Getting refs to wrapped class components

我有一个包含子边栏组件的地图组件。我正在尝试做一个相对简单的任务,即在单击地图标记时滚动到侧边栏中位置列表中的位置。但是,因为边栏需要包裹在 withRouterconnect 中,我无法在地图组件中设置 ref (ref) => this.sidebar = ref

export class Map extends React.Component {
  ...

  handleClick() {
    this.sidebar.scrollToPlace(place.id);
  }

  render () {
    return (
      <MapSidebar
        // unable to set ref
      />
    )
  }
}

class MapSidebar extends React.Component {
  ...

  scrollToPlace(id) {
    this.refs[id].scrollIntoView({block: 'end', behavior: 'smooth'});
  }
}
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(MapSidebar));

我知道使用 wrappedComponentRef 可以获得 withRouter 的内容,但我仍然有 connect 需要处理。

我还尝试在 MapSidebar 实例上创建自定义引用:

<MapSidebar
  getReference={(ref) => {
    this.sidebar = ref;
  }} />

然后在 MapSidebar class 构造函数中,调用:

if(this.props.getReference) {
  this.props.getReference(this);
}

但这导致了该组件更新的无限循环(虽然我不确定我明白为什么)。

是否有更好的方法来解决这些问题?

我建议您避免使用 refs 并简单地向下传递滚动值:

export class Map extends React.Component {
  ...

  handleClick() {
    this.setState({scrollToPlaceId: place.id});
  }

  render () {
    return (
      <MapSidebar
        // Add a new property
        scrollToPlace={this.state.scrollToPlaceId}
      />
    )
  }
}

然后在你的侧边栏组件中,只听 componentWillReceiveProps 中的滚动变化,例如

class MapSidebar extends React.Component {
  ...

  componentWillReceiveProps(nextProps) {
    if (nextProps.scrollToPlace !== this.props.scrollToPlace) {
      this.refs[nextProps.scrollToPlace].scrollIntoView({block: 'end', behavior: 'smooth'});
    }
  }
}
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(MapSidebar));

在 类:

中存储引用
// MapSidebar render - add this to the element you want.
<div ref={r => (this.ref = r)}>

然后在地图渲染中:

<MapSidebar ref={r => (this.sidebar = r)}>

现在在 Map 安装后您可以访问 ref:

this.sidebar.ref