获取无状态组件中的引用

Hok*_*imo 2 ecmascript-6 reactjs

我想滚动到列表的最后一项,如果没有新组件,则可以毫无问题地实现它。

这是工作代码 https://codesandbox.io/s/zn12r4p9ym

export default class App extends React.Component {
  componentDidMount() {
    this.lastNode && this.lastNode.scrollIntoView(false);
  }
  render() {
    return (
      <div className="App">
        <div style={{ height: "70px", overflow: "auto" }}>
          <p>1</p>
          <p>2</p>
          <p>3</p>
          <p>4</p>
          <p>5</p>
          <p ref={el => (this.lastNode = el)}>6</p>
        </div>
      </div>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我的列表在新文件中怎么办?像<List />,我如何获得推荐<List />?

Aru*_*hit 5

基本上,您试图将子组件的DOM Refs公开List给其父组件App。如果您使用React 16.3或更高版本,官方文档建议在这种情况下使用ref转发。

引用转发是一种选择加入功能,它使某些组件可以接收它们收到的引用,并将其进一步向下传递(即“转发”)给孩子。

这是使用Ref转发解决此问题的演示。

const List = React.forwardRef((props, ref) => {
  return (
    <React.Fragment>
      <p>1</p>
      <p>2</p>
      <p>3</p>
      <p>4</p>
      <p>5</p>
      <p ref={ref}>6</p>
    </React.Fragment>
  )
});


class App extends React.Component {
  constructor(props) {
    super(props);
    this.lastListNoderef = React.createRef();
  }

  componentDidMount() {
    this.lastListNoderef && this.lastListNoderef.current.scrollIntoView(false);
  }

  render() {
    return (
      <div className="App">
        <div style={{ height: "70px", overflow: "auto" }}>
          <List ref={this.lastListNoderef}/>
        </div>
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Run Code Online (Sandbox Code Playgroud)
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>

<div id="root"></div>
Run Code Online (Sandbox Code Playgroud)

使用回调引用:

如果您使用React 16.2或更低版本,或者您需要比ref转发所提供的更多的灵活性,则可以使用此替代方法并将ref作为不同名称的prop显式传递。

例:

const List = (props) => {
  return (
    <React.Fragment>
      <p>1</p>
      <p>2</p>
      <p>3</p>
      <p>4</p>
      <p>5</p>
      <p ref={props.inputRef}>6</p>
    </React.Fragment>
  )
};

class App extends React.Component {
  componentDidMount() {
    this.lastListNoderef && this.lastListNoderef.scrollIntoView(false);
  }

  render() {
    return (
      <div className="App">
        <div style={{ height: "70px", overflow: "auto" }}>
          <List inputRef={el => this.lastListNoderef = el} />
        </div>
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Run Code Online (Sandbox Code Playgroud)
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>

<div id="root"></div>
Run Code Online (Sandbox Code Playgroud)