【问题标题】:Navigate to another screen from Flat list item从平面列表项导航到另一个屏幕
【发布时间】:2018-09-03 16:46:20
【问题描述】:

当我单击平面列表中的一个项目时,我正试图导航到另一个屏幕。

我在这里的代码工作了几天,但现在它没有,当应用程序加载时,EventDetailScreen 甚至在我点击任何平面列表项之前打开,然后当我按下EventDetailScreen 中的后退按钮将我带回 EventListScreen,如果我单击任何列表项,则没有任何反应,也不会被带到 EventDetailScreen。

我也得到一个错误:

警告:在现有状态转换期间无法更新(例如在render 或其他组件的构造函数中)。渲染方法应该是 props 和 state 的纯函数;构造函数副作用是一种反模式,但可以移至componentWillMount

我是 React Native 的新手,非常感谢任何帮助!

我正在使用: "react-navigation": "^2.7.0","react": "16.4.1", "react-native": "0.56.0",

我在 SO 上使用了这个答案 Navigating to each item in FlatList 来让它开始工作。

EventListScreen.js

export default class EventListScreen extends Component {

constructor() {
    super();
    this.ref = firebase.firestore();
    this.unsubsribe = null;

    this.state = {
        eventName: '',
        eventLocation: '',
        loading: true,
        events: [],
    };
}

componentDidMount() {
    console.log('EventsListScreen1');
    this.unsubsribe = this.ref.onSnapshot(this.onCollectionUpdate)
}

componentWillUnmount() {
    this.unsubsribe();
}


openDetails = () => {
    this.props.navigation.navigate('EventDetailScreen');
};

render() {

    if (this.state.loading) {
        return null;
    }

    return (
        <Container>

            <FlatList
                data={this.state.events}
                // Get the item data by referencing as a new function to it
                renderItem={({item}) =>
                    <Event
                    openDetails={() => this.openDetails()}
                    {...item} />}
            />

            <View style={{flex: 1}}>
                <Fab
                    active={this.state.active}
                    direction="left"
                    containerStyle={{}}
                    style={{backgroundColor: '#5067FF'}}
                    position="bottomRight"
                    onPress={() => 
                    this.props.navigation.navigate('EventForm')
                    }>
                    <Icon 
                       name="ios-add"/>
                </Fab>
            </View>

        </Container>
    );
}

Event.js

export default class Event extends Component {

render() {

    return (
        <Card>
            <CardSection>
                <Text>{this.props.eventName}</Text>
            </CardSection>

            <TouchableOpacity
              onPress={this.props.openDetails()}
            >
            <CardSection>
                <Image
                    style={{
                       width: 350,
                       height: 300
                    }}
                    source={{
                       uri: this.props.imageDownloadUrl
                    }}
                />
            </CardSection>

            <CardSection>
                <Text>{this.props.eventLocation}</Text>
            </CardSection>
            </TouchableOpacity>
        </Card>
    );
}};

EventDetailScreen.js

export default class EventDetailScreen extends Component {
render() {
    /* 2. Get the param, provide a fallback value if not available */
    const { navigation } = this.props;
    const itemId = navigation.getParam('itemId', 'NO-ID');

    return (
        <View 
           style={{ 
              flex: 1,
              alignItems: 'center',
              justifyContent: 'center' 
            }}>
            <Text>Details Screen</Text>
        </View>
    );
}}

【问题讨论】:

    标签: javascript reactjs react-native react-navigation react-native-flatlist


    【解决方案1】:

    这可能是因为Event 组件中的以下行。

    <TouchableOpacity
        onPress={this.props.openDetails()} // <-- this line to be specific
     > ... </>
    

    一旦EventScreenList 呈现列表,第一行就会执行切换屏幕的openDetails() 方法。

    您可以使用onPress={() =&gt; this.props.openDetails()} 来避免这种情况。

    在 EventScreenList 组件的构造函数或 componentDidMount 中包含以下内容也是一个好主意,因为这两个函数都使用 this 语句的上下文。

    this.openDetails = this.openDetails.bind(this);
    this.onCollectionUpdate = this.onCollectionUpdate.bind(this);
    

    要检查上述语句的重要性, 试试

    <TouchableOpacity
        onPress={this.props.openDetails} // <-- this line
     > ... </>
    

    警告消息是由于状态更新完成之前的导航。

    【讨论】:

    • 非常感谢,您能否再解释一下为什么将上述两种方法添加到构造函数或componentDidMount 是一个好主意?有没有可以推荐的教程,谢谢
    • @Priyesh 试图解释的是您应该将函数绑定到“this”。我不确定你是否真的需要绑定它,因为你正在使用箭头函数,它会自动将你的范围绑定到这个
    • @AndrewIrwin 您可以阅读此问题以获取更多详细信息。 stackoverflow.com/questions/45998744/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-09
    • 1970-01-01
    • 2018-02-25
    • 2019-10-20
    • 1970-01-01
    相关资源
    最近更新 更多