从ListView导航问题

时间:2018-03-12 05:34:04

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

我的主页(listviewTodoDetail.js)中有2个TodoDetailChecked.js,此TouchableOpacity&#39中有listview个; s行..当我点击此TouchableOpacity时,我想转到P rofile.js页面。 但问题是当我点击时,它找不到props.navigation.navigate。 我试图抓住componentDidMount中的日志,但没有关于导航。

componentDidMount() {
    console.log(this.props);
  }

请帮帮我......

这是代码;

TodoDetail.js

import React, { Component } from 'react';
import { Card, Icon } from 'react-native-elements';
// import Checkbox from '../components/Checkbox';
import { Text, View, TouchableOpacity } from 'react-native';
import * as firebase from 'firebase';
import {
    Menu,
    MenuOptions,
    MenuOption,
    MenuTrigger,
  } from 'react-native-popup-menu';

class TodoDetail extends Component {

  componentDidMount() {
    console.log(this.props.navigation.navigate('TodoDetail'));
  }
  clickText() {
    const { todo } = this.props.todos;   
    // const { navigate } = this.props.navigation; 
    return (
      <TouchableOpacity onPress={this.seeDetail.bind(this)} >
        <Text numberOfLines={1}> {todo} </Text>
      </TouchableOpacity>
    );
  }
  seeDetail() {
    const { navigate } = this.props.navigation;
    navigate("Profile", { name: "Jane" });
    console.log('click');
  }

  render() {
    //Serverdan çekilenler
    const uid = this.props.todos.uid;
    const success = this.props.todos.success;
    //Tarih olayları
    const date = new Date();
    const day = date.getDate();
    const tomorrow = day + 1;
    const year = date.getFullYear();
    const month = date.getMonth();
    //Style tanımlama
    const { container, iconContainer, subContainer } = styles; 

    if (success === 0) {
    return (  
        <Card>
         <View style={container}>
        <View style={iconContainer}>        
            <TouchableOpacity onPress={() => firebase.database().ref(`todos/personal/${uid}/success`).set(1)} >
                <Icon name='check-box-outline-blank' />
            </TouchableOpacity>
        <View style={subContainer}>                    
            {this.clickText()}
        </View>
        <View style={iconContainer}>                
        <Menu>
      <MenuTrigger>
      <Icon name='keyboard-arrow-down' />
      </MenuTrigger>
      <MenuOptions>
        <MenuOption onSelect={() => firebase.database().ref(`todos/personal/${uid}/date`).set({ day, year, month })} >
          <Text style={{ color: 'black' }} > Son Tarihi Bugün </Text>
        </MenuOption>
        <MenuOption onSelect={() => firebase.database().ref(`todos/personal/${uid}/date`).set({ day: tomorrow, year, month })} >
          <Text style={{ color: 'black' }} > Son Tarihi Yarın </Text>
        </MenuOption>
        <MenuOption onSelect={() => firebase.database().ref(`todos/personal/${uid}/date`).remove()} >
          <Text style={{ color: 'black' }} > Son Tarihi Kaldır </Text>
        </MenuOption>
        <MenuOption onSelect={() => firebase.database().ref(`todos/personal/${uid}`).remove()} >
          <Text style={{ color: 'red' }} > Yapılacak İşi Sil </Text>
        </MenuOption>
      </MenuOptions>
    </Menu>
        </View>
        </View>
    </View>
      </Card>
    );
  } else
    if (success === 1) {
     return (  
       null
    );
  }
  }
}

Todolist.js

createDataSource({ studentsArray }) {
  const ds = new ListView.DataSource({
    rowHasChanged: (r1, r2) => r1 !== r2
  });
  this.dataSource = ds.cloneWithRows(studentsArray.reverse());
}
changeScreen() {
  this.setState({ screenSize: false });
}
changeScreenBack() {
  this.setState({ screenSize: true });
}
renderRow(todos) {
  return <TodoDetail todos={todos} />;
}
renderRow2(todos) {
  return <TodoDetailChecked todos={todos} />;
}
render() {
  // const { navigate } = this.props.navigation;      

  const { container, inputContainer, inputText } = styles;
 if (!this.state.screenSize) {
  return (
    <View style={container} >
        <View style={inputContainer} >
        <Icon name={'add'} />
        <TextInput
            style={inputText}
            underlineColorAndroid='transparent'
            placeholder="Yapılacak iş ekle..."
            placeholderTextColor="#FFFFFF"
            value={this.props.todo}            
            onChangeText={todo => this.props.todoChanged(todo)}
        />
        <Button
          onPress={this.addToDo.bind(this)}
          title="Ekle"
          color="#841584"
          accessibilityLabel="Learn more about this purple button"
        />
    </View>
    <View style={{ flex: 1 }}>
    <View style={{ flex: 1 }}>
    <ListView
            enableEmptySections
            dataSource={this.dataSource}
            renderRow={this.renderRow}
    />
    </View>    
    <View style={{ flex: 1 }}>
    <View style={{ height: 1, backgroundColor: 'gray' }} />    
    <ListView
            enableEmptySections
            dataSource={this.dataSource}
            renderRow={this.renderRow2}
    />
    </View>    
    </View>
    <Button
      onPress={this.changeScreenBack.bind(this)}
      title="Tamamlananları Gizle"
      color="#841584"
    />
      </View>    
    );
  } else
  if (this.state.screenSize) {
    return (
      <View style={container} >
      <View style={inputContainer} >
      <Icon name={'add'} />
      <TextInput
        style={inputText}
        underlineColorAndroid='transparent'
        placeholder="Yapılacak iş ekle..."
        placeholderTextColor="#FFFFFF"
        value={this.props.todo}            
        onChangeText={todo => this.props.todoChanged(todo)}
      />
      <Button
        onPress={this.addToDo.bind(this)}
        title="Ekle"
        color="#841584"
      />
      </View>
      <View style={{ flex: 1 }}>
      <ListView
        enableEmptySections
        dataSource={this.dataSource}
        renderRow={this.renderRow}
      />
      <Button
      onPress={this.changeScreen.bind(this)}
      title="Tamamlananları Göster"
      color="#841584"
      />
      </View>    
      </View>
      );
  }
  }
}

Router.js

import { StackNavigator } from 'react-navigation';
import Todolist from './src/Todolist';
import Profile from './src/Profile';
import TodoDetail from './components/TodoDetail';
import TodoDetailChecked from './components/TodoDetailChecked';
import TodoPage from './components/TodoPage';

const Router = StackNavigator({
    Todolist: { screen: Todolist },
    TodoDetail: { screen: TodoDetail },    
    Profile: { screen: Profile },
    TodoDetailChecked: { screen: TodoDetailChecked },
    TodoPage: { screen: TodoPage }
  });


export default Router;

1 个答案:

答案 0 :(得分:0)

关于父母问题的这个问题。

来自documentation的引用:

  

重要的是要注意,只有在屏幕显示时才会发生这种情况   通过React Navigation呈现为路线(例如,响应于   this.props.navigation.navigate)。例如,如果我们渲染   DetailsScreen作为HomeScreen的孩子,然后DetailsScreen不会   提供导航道具,当你按下   主屏幕上的"Go to Details... again"按钮,应用程序将抛出其中一个   典型的JavaScript异常"undefined is not an object"

要解决您的问题,请将this.props.navigation传递给更高组件的子组件。

让我们举例:

<强> App.js

import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import MyView from './MyView';
import { StackNavigator } from 'react-navigation';
import DetailsScreen from './DetailsScreen';

class App extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <MyView navigation={this.props.navigation} />
        <Text>Open up App.js to start working on your app!</Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

export default StackNavigator({
  Home: {
    screen: App,
  },
  Details: {
    screen: DetailsScreen,
  }
});

<强> MyView.js

import React from 'react';
import { StyleSheet, Text, ListView } from 'react-native';
import TodoDetail from './TodoDetail';

export default class MyView extends React.Component {
    constructor() {
        super();
        const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
        this.state = {
            dataSource: ds.cloneWithRows(['todo 1', 'todo 2']),
        };
    }
    renderRow(todos) {
        return <TodoDetail todos={todos} navigation={this.props.navigation} />;
    }

    render() {
        return (
            <ListView
                enableEmptySections
                dataSource={this.state.dataSource}
                renderRow={(rowData) => this.renderRow(rowData)}
            />
        );
    }
}

<强> TodoDetail.js

import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';

export default class TodoDetail extends React.Component {
    componentDidMount() {
        // console.log(this.props.navigation.navigate('Details'));
    }

    render() {
        return (
            <View>
                <Text>Todo detail</Text>
                <Text>{this.props.todos}</Text>
                <Button
                    title="Go to Details"
                    onPress={() => this.props.navigation.navigate('Details', { itemDetail: this.props.todos })}
                />
            </View>
        );
    }
}

<强> DetailsS​​creen.js

import React from 'react';
import { StyleSheet, Text, View } from 'react-native';

export default class DetailsScreen extends React.Component {
    componentDidMount() {
        console.log(this.props.navigation);
    }

    render() {
        const { params } = this.props.navigation.state;
        return (
            <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
                <Text>Details Screen</Text>
                <Text>{ params.itemDetail }</Text>
            </View>
        );
    }
}

所以在这里,你需要传递navigation={this.props.navigation}每个子渲染。如果您看到MyView组件传递navigation道具<MyView navigation={this.props.navigation} />

<TodoDetail todos={todos} navigation={this.props.navigation} />内部,TodoDetail可以使用this.props.navigation访问this.props.navigation.navigate