当 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.myRef
或 this.props.data
未定义。
观察:
this.myRef
最快只能在componentDidMount
使用。
this.props
在 componentDidMount
中未定义,因为它需要时间
让 this.props
阅读使用(ready
我的意思是,有值,被定义)
- 在
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,
});
}
}
}
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.myRef
或 this.props.data
未定义。
观察:
this.myRef
最快只能在componentDidMount
使用。this.props
在componentDidMount
中未定义,因为它需要时间 让this.props
阅读使用(ready
我的意思是,有值,被定义)- 在
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,
});
}
}
}