当 props 准备好时使用 ref

Use ref when props is ready

export default class Test extends Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }

  componentDidMount() {
    if (this.props.data.length) {
      this.myRef.current.scrollToIndex({
        index: this.props.index,
      });
    }
  }

  render() {
    return (
      <FlatList
        ref={this.myRef}
        data={this.props.data}
        renderItem={this.renderItem}
        getItemLayout={(data, index) => ({
          length: 50,
          offset: 100 * index,
          index,
        })}
      />
    );
  }
}

目标: 一旦组件呈现,FlatList 应该自动向下滚动到具有 index === this.props.index 的项目(想象一个即时消息应用程序,您希望自动向下滚动到一条消息)

问题: this.myRefthis.props.data 未定义。

观察:

  1. this.myRef最快只能在componentDidMount使用。
  2. this.propscomponentDidMount 中未定义,因为它需要时间 让 this.props 阅读使用(ready 我的意思是,有值,被定义)
  3. getDerivedStateFromProps 中,我检查了 this.props 是否准备就绪,但是 this.myRef 仍未定义。 (也许现在初始化还为时过早)

我怎样才能实现我的目标?

System:
    OS: macOS 10.15.3
    CPU: (4) x64 Intel(R) Core(TM) i5-5257U CPU @ 2.70GHz
    Memory: 122.77 MB / 8.00 GB
    Shell: 5.7.1 - /bin/zsh
  Binaries:
    Node: 12.13.1 - ~/.nvm/versions/node/v12.13.1/bin/node
    npm: 6.12.1 - ~/.nvm/versions/node/v12.13.1/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  SDKs:
    iOS SDK:
      Platforms: iOS 13.2, DriverKit 19.0, macOS 10.15, tvOS 13.2, watchOS 6.1
    Android SDK:
      API Levels: 28, 29
      Build Tools: 28.0.3, 29.0.2
      System Images: android-28 | Google APIs Intel x86 Atom, android-29 | Google APIs Intel x86 Atom
  IDEs:
    Android Studio: 3.5 AI-191.8026.42.35.5977832
    Xcode: 11.3.1/11C504 - /usr/bin/xcodebuild
  npmPackages:
    react: 16.9.0 => 16.9.0
    react-native: https://github.com/expo/react-native/archive/sdk-36.0.1.tar.gz => 0.61.4

componentDidMount 仅在第一次渲染后调用一次,但如果您的数据尚未准备好,您将没有第二次机会向下滚动。

您应该删除 componentDidMount 并将其替换为 componentDidUpdate 以处理 props.data 中的更改:

componentDidUpdate(prevProps) {
    if (this.props.data !== prevProps.data) {
        if (this.props.data.length) {
            this.myRef.current.scrollToIndex({
                index: this.props.index,
            });
        }
    }
}