我正在渲染餐厅菜单,并将其显示在ScrollView
中。
由于某种原因,我第一次渲染屏幕时,一切工作正常。但是,如果我离开屏幕并再次导航到该屏幕,并且我console.log
this.state.catTitlesXVals
和this.state.catTitlesWidthsSorted
拥有默认状态,这些默认值是在该状态下初始化的。我使用这些功能是为了获得这种效果,您可以在下面的类别中看到:
我不明白为什么第二次导航到屏幕并挂载屏幕时,下面的功能无法正确更新状态。
我真的在这里迷路了,任何帮助将不胜感激。预先谢谢你:)
componentDidUpdate() {
// since onLayout for some (weird) reason returns the widths in an unsorted manner,
// we will sort them since we know that x has to be always in ascending order and
// we can use that as a reference
if (this.state.catTitlesXvals.length == this.state.numCategories && !this.state.catTitlesWidthsSorted) {
this.setState({ catTitlesWidthsSorted: true }, () => {
var temp = [];
var xvals = this.state.catTitlesXvals;
var i;
for (i = 0; i < this.state.catTitlesXvals.length; i++) {
var index;
var obj = this.state.catTitlesWidthsRef[i];
index = xvals.indexOf(Number(Object.keys(obj)[0]));
temp[index] = obj[xvals[index].toString()]
}
this.setState({ catTitlesWidths: temp, translateWidth: new Animated.Value(temp[0]) })
})
}
}
_onLayoutCategories = ({ nativeEvent: { layout: { x, y, width, height } } }) => {
this.setState(prevState => ({
categoryYvals: [...prevState.categoryYvals, y].sort(function (a, b) { return a - b })
}))
};
_onLayoutCatTitles = ({ nativeEvent: { layout: { x, y, width, height } } }) => {
this.setState(prevState => ({
catTitlesWidths: [...prevState.catTitlesWidths, width],
catTitlesXvals: [...prevState.catTitlesXvals, x].sort(function (a, b) { return a - b }),
catTitlesWidthsRef: [...prevState.catTitlesWidthsRef, { [x]: width }]
}))
};
handleScroll = (event) => {
var y = event.nativeEvent.contentOffset.y
for (let i = 0; i < this.state.categoryYvals.length; i++) {
if (y > this.state.categoryYvals[i] && y < this.state.categoryYvals[i + 1]) {
let translateValueX = this.state.catTitlesXvals[i];
let translateValueW = this.state.catTitlesWidths[i];
Animated.parallel([
Animated.timing(
this.state.translateX,
{
toValue: translateValueX,
duration: 75,
}
),
Animated.timing(
this.state.translateWidth,
{
toValue: translateValueW,
duration: 50,
}
)
]).start()
}
}
}
render() {
return (
<View style={styles.container}>
...
<ScrollView stickyHeaderIndices={[0]} ref={(node) => this.scroll = node} onScroll={this.handleScroll} scrollEventThrottle={1}>
<View style={{ flex: 1, backgroundColor: 'white', paddingTop: 45 }}>
...
<ScrollView style={{ backgroundColor: 'white', borderBottomColor: 'orange', borderBottomWidth: 1 }}
horizontal={true}
showsHorizontalScrollIndicator={false}
ref={(node) => this.scrollTitles = node}>
<View style={{ flexDirection: 'row', alignItems: 'center', height: 50 }}>
{getCatTitles(this.props.route.params['menu'])}
</View>
<Animated.View style={[styles.highlight, { left: this.state.translateX, width: this.state.translateWidth }]}></Animated.View>
</ScrollView>
</View>
{DisplayMenu(this.props.route.params['menu'], this)}
...
function DisplayMenu(MenuText, defaultThis) {
var menu = JSON.parse(MenuText);
var CategoriesNum;
CategoriesNum = menu.length;
var i;
var components = [];
for (i = 1; i < CategoriesNum + 1; i++) {
let catTitle = menu[i - 1][i.toString()]["catTitle"]
var temp =
(<View style={styles.category} key={'cat_' + i} onLayout={defaultThis._onLayoutCategories}>
<Text style={styles.catTitle}>{catTitle}</Text>
<View style={styles.catItems}>
{generateItemC(menu, i, defaultThis)}
</View>
</View>);
components[i] = temp;
}
return (
<View>{components}</View>
)
}