2

我有一个包含子侧边栏组件的地图组件。我正在尝试执行一项相对简单的任务,即在单击地图标记时滚动到侧边栏中的位置列表中的位置。但是,因为侧边栏需要包裹在withRouterand中connect,所以我无法(ref) => this.sidebar = ref在地图组件中设置 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));

我知道 usingwrappedComponentRef可以让我获得 的内容withRouter,但是我仍然需要connect处理。

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

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

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

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

但这导致该组件更新的无限循环(尽管我不确定我理解为什么)。

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

4

2 回答 2

1

我建议您避免使用 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));
于 2018-01-04T02:48:09.740 回答
1

在两个类中存储一个引用:

// 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
于 2018-05-31T20:16:24.967 回答