无法在 ScrollableTabView 中呈现视图
Unable to render View inside ScrollableTabView
我是 React Native 的新手,我正在尝试使用这个包 https://github.com/LiuC520/react-native-scrollable-tab-view-forked 来使用选项卡,这就是选项卡的创建方式
<ScrollableTabView
renderTabBar={() => (
<ScrollableTabBar
style={styles.scrollStyle}
tabStyle={styles.tabStyle}
/>
)}
tabBarTextStyle={styles.tabBarTextStyle}
tabBarInactiveTextColor={'black'}
tabBarActiveTextColor={'red'}
tabBarUnderlineStyle={styles.underlineStyle}
initialPage={2}
>
<View key={'1'} tabLabel={'firt tab '} style={{flex:1,backgroundColor:'red'}}/>
<View key={'2'} tabLabel={'second tab'} style={{flex:1,backgroundColor:'blue'}}/>
<View key={'3'} tabLabel={'third tab'} style={{flex:1,backgroundColor:'yellow'}}/>
</ScrollableTabView>
而且工作正常
但是当我尝试渲染视图以在我失败的每个选项卡中显示它时,我已经尝试过这种方式
<View key={'1'} tabLabel={'firt tab '} style={{flex:1,backgroundColor:'red',height:100}}>
<View><Text>first</Text></View>
</View>
但它给出了错误 "TypeError: JSON.stringify cannot serialize cyclic structure",我不明白那是什么意思,如果有人已经使用过这个包或知道解决方案是什么,请帮助。
这是我的全部代码
import React from 'react';
import { ScrollView, ImageBackground, Image, View, StyleSheet,
StatusBar, Dimensions, Platform } from 'react-native';
import { Block, Button, Text, theme } from 'galio-framework';
import ScrollableTabView, { DefaultTabBar, ScrollableTabBar } from 'react-native-scrollable-tab-view-forked';
const { height, width } = Dimensions.get('screen');
import { Images, argonTheme } from '../constants/';
import { HeaderHeight } from "../constants/utils";
import ajax from '../services/FetchSubjects';
import Loader from '../components/Loader';
const URI = 'http://localhost:8000';
export default class SubjectDetails extends React.Component {
constructor(props) {
super(props);
this.state = {
loading: true,
data: {
subject: {},
meals: []
}
}
}
async componentDidMount() {
const data = await ajax.fetchSubjectDetails(this.props.navigation.state.params.subjectId);
this.setState({
data: {
subject: data.subject,
meals: data.meals
},
loading: false
});
}
render() {
const { navigation } = this.props;
return (
<Block safe style={styles.container}>
<Block>
<StatusBar barStyle="light-content" />
<Loader loading={this.state.loading} />
<Block flex style={styles.category}>
<ImageBackground
source={this.state.loading ? Images.Pro : { uri: URI + this.state.data.subject.cover.url }}
style={{ flex: 1, height: 160, width, zIndex: 1 }}
>
<Block style={styles.categoryBg}>
<Block style={styles.categoryTitle}>
<Text size={18} bold color={theme.COLORS.WHITE}>
{this.state.data.subject.name}
</Text>
</Block>
</Block>
</ImageBackground>
</Block>
</Block>
<Block style={{marginTop:160,height:"100%"}}>
<ScrollView>
<ScrollableTabView
renderTabBar={() => (
<ScrollableTabBar
style={styles.scrollStyle}
tabStyle={styles.tabStyle}
/>
)}
tabBarTextStyle={styles.tabBarTextStyle}
tabBarInactiveTextColor={'black'}
tabBarActiveTextColor={'#2B4D8E'}
tabBarUnderlineStyle={styles.underlineStyle}
initialPage={2}
>
<View key={'1'} tabLabel={'firt tab '} style={{flex:1,backgroundColor:'red',height:100}}><Text>Lorem ipsum</Text></View>
<View key={'2'} tabLabel={'second tab'} style={{flex:1,backgroundColor:'blue',height:100}}/>
<View key={'3'} tabLabel={'third tab'} style={{flex:1,backgroundColor:'yellow',height:100}}/>
<View key={'4'} tabLabel={'Fourth tab'} style={{flex:1,backgroundColor:'yellow',height:100}}/>
</ScrollableTabView>
</ScrollView>
</Block>
</Block>
);
}
}
ok,我看了react-native-scroll-tab-view
和react-native-scroll-tab-view-forked
的源码,发现有些代码不一样,所以才导致你的问题。你应该使用 react-native-scroll-tab-view
.
原因是:
首先我们看源码,ScrollTabview位于index.js,我只展示核心代码
// this is react-native-scroll-tab-view code
let tabBarProps = {
goToPage: this.goToPage,
tabs: this._children().map((child) => child.props.tabLabel), //this is the diffent
activeTab: this.state.currentPage,
scrollValue: this.state.scrollValue,
containerWidth: this.state.containerWidth,
};
// this is the fork project
const tabBarProps = {
goToPage: this.goToPage,
tabs: this._children().map(child => child.props), //this is the diffent
activeTab: this.state.currentPage,
scrollValue: this.state.scrollValue,
// containerWidth: this.props.containerWidth,
containerWidth: this.props.tabsWidth || this.props.containerWidth,
initialPage:this.props.initialPage,
}
// the tabs in the fored is not according by tablabel.
// then it will call the this.renderTabBar method
return <View style={[styles.container, this.props.style, ]} onLayout={this._handleLayout}>
{this.props.tabBarPosition === 'top' && this.renderTabBar(tabBarProps)}
{this.renderScrollableContent()}
{(this.props.tabBarPosition === 'bottom' || overlayTabs) && this.renderTabBar(tabBarProps)}
</View>;
//in this.renderTabBar, you define the method, so it will call this.props.renderTabBar
renderTabBar(props) {
if (this.props.renderTabBar === false) {
return null;
} else if (this.props.renderTabBar) {
return React.cloneElement(this.props.renderTabBar(props), props);
} else {
return <DefaultTabBar {...props} />;
}
},
// then, we look at the ScrollTabBar soruce code, which will render tabs
//here it call the JSON.stringfy, so here it is your errors occur
componentDidUpdate(prevProps) {
// If the tabs change, force the width of the tabs container to be recalculated
if (JSON.stringify(prevProps.tabs) !== JSON.stringify(this.props.tabs) && this.state._containerWidth) {
this.setState({ _containerWidth: null, });
}
},
希望对您有所帮助!
我是 React Native 的新手,我正在尝试使用这个包 https://github.com/LiuC520/react-native-scrollable-tab-view-forked 来使用选项卡,这就是选项卡的创建方式
<ScrollableTabView
renderTabBar={() => (
<ScrollableTabBar
style={styles.scrollStyle}
tabStyle={styles.tabStyle}
/>
)}
tabBarTextStyle={styles.tabBarTextStyle}
tabBarInactiveTextColor={'black'}
tabBarActiveTextColor={'red'}
tabBarUnderlineStyle={styles.underlineStyle}
initialPage={2}
>
<View key={'1'} tabLabel={'firt tab '} style={{flex:1,backgroundColor:'red'}}/>
<View key={'2'} tabLabel={'second tab'} style={{flex:1,backgroundColor:'blue'}}/>
<View key={'3'} tabLabel={'third tab'} style={{flex:1,backgroundColor:'yellow'}}/>
</ScrollableTabView>
而且工作正常
但是当我尝试渲染视图以在我失败的每个选项卡中显示它时,我已经尝试过这种方式
<View key={'1'} tabLabel={'firt tab '} style={{flex:1,backgroundColor:'red',height:100}}>
<View><Text>first</Text></View>
</View>
但它给出了错误 "TypeError: JSON.stringify cannot serialize cyclic structure",我不明白那是什么意思,如果有人已经使用过这个包或知道解决方案是什么,请帮助。
这是我的全部代码
import React from 'react';
import { ScrollView, ImageBackground, Image, View, StyleSheet,
StatusBar, Dimensions, Platform } from 'react-native';
import { Block, Button, Text, theme } from 'galio-framework';
import ScrollableTabView, { DefaultTabBar, ScrollableTabBar } from 'react-native-scrollable-tab-view-forked';
const { height, width } = Dimensions.get('screen');
import { Images, argonTheme } from '../constants/';
import { HeaderHeight } from "../constants/utils";
import ajax from '../services/FetchSubjects';
import Loader from '../components/Loader';
const URI = 'http://localhost:8000';
export default class SubjectDetails extends React.Component {
constructor(props) {
super(props);
this.state = {
loading: true,
data: {
subject: {},
meals: []
}
}
}
async componentDidMount() {
const data = await ajax.fetchSubjectDetails(this.props.navigation.state.params.subjectId);
this.setState({
data: {
subject: data.subject,
meals: data.meals
},
loading: false
});
}
render() {
const { navigation } = this.props;
return (
<Block safe style={styles.container}>
<Block>
<StatusBar barStyle="light-content" />
<Loader loading={this.state.loading} />
<Block flex style={styles.category}>
<ImageBackground
source={this.state.loading ? Images.Pro : { uri: URI + this.state.data.subject.cover.url }}
style={{ flex: 1, height: 160, width, zIndex: 1 }}
>
<Block style={styles.categoryBg}>
<Block style={styles.categoryTitle}>
<Text size={18} bold color={theme.COLORS.WHITE}>
{this.state.data.subject.name}
</Text>
</Block>
</Block>
</ImageBackground>
</Block>
</Block>
<Block style={{marginTop:160,height:"100%"}}>
<ScrollView>
<ScrollableTabView
renderTabBar={() => (
<ScrollableTabBar
style={styles.scrollStyle}
tabStyle={styles.tabStyle}
/>
)}
tabBarTextStyle={styles.tabBarTextStyle}
tabBarInactiveTextColor={'black'}
tabBarActiveTextColor={'#2B4D8E'}
tabBarUnderlineStyle={styles.underlineStyle}
initialPage={2}
>
<View key={'1'} tabLabel={'firt tab '} style={{flex:1,backgroundColor:'red',height:100}}><Text>Lorem ipsum</Text></View>
<View key={'2'} tabLabel={'second tab'} style={{flex:1,backgroundColor:'blue',height:100}}/>
<View key={'3'} tabLabel={'third tab'} style={{flex:1,backgroundColor:'yellow',height:100}}/>
<View key={'4'} tabLabel={'Fourth tab'} style={{flex:1,backgroundColor:'yellow',height:100}}/>
</ScrollableTabView>
</ScrollView>
</Block>
</Block>
);
}
}
ok,我看了react-native-scroll-tab-view
和react-native-scroll-tab-view-forked
的源码,发现有些代码不一样,所以才导致你的问题。你应该使用 react-native-scroll-tab-view
.
原因是:
首先我们看源码,ScrollTabview位于index.js,我只展示核心代码
// this is react-native-scroll-tab-view code
let tabBarProps = {
goToPage: this.goToPage,
tabs: this._children().map((child) => child.props.tabLabel), //this is the diffent
activeTab: this.state.currentPage,
scrollValue: this.state.scrollValue,
containerWidth: this.state.containerWidth,
};
// this is the fork project
const tabBarProps = {
goToPage: this.goToPage,
tabs: this._children().map(child => child.props), //this is the diffent
activeTab: this.state.currentPage,
scrollValue: this.state.scrollValue,
// containerWidth: this.props.containerWidth,
containerWidth: this.props.tabsWidth || this.props.containerWidth,
initialPage:this.props.initialPage,
}
// the tabs in the fored is not according by tablabel.
// then it will call the this.renderTabBar method
return <View style={[styles.container, this.props.style, ]} onLayout={this._handleLayout}>
{this.props.tabBarPosition === 'top' && this.renderTabBar(tabBarProps)}
{this.renderScrollableContent()}
{(this.props.tabBarPosition === 'bottom' || overlayTabs) && this.renderTabBar(tabBarProps)}
</View>;
//in this.renderTabBar, you define the method, so it will call this.props.renderTabBar
renderTabBar(props) {
if (this.props.renderTabBar === false) {
return null;
} else if (this.props.renderTabBar) {
return React.cloneElement(this.props.renderTabBar(props), props);
} else {
return <DefaultTabBar {...props} />;
}
},
// then, we look at the ScrollTabBar soruce code, which will render tabs
//here it call the JSON.stringfy, so here it is your errors occur
componentDidUpdate(prevProps) {
// If the tabs change, force the width of the tabs container to be recalculated
if (JSON.stringify(prevProps.tabs) !== JSON.stringify(this.props.tabs) && this.state._containerWidth) {
this.setState({ _containerWidth: null, });
}
},
希望对您有所帮助!