Passprops equivalent for Navigator?

China☆狼群 提交于 2019-12-12 07:26:54

问题


I am trying to convert from NavigatorIOS to Navigator and can't seem to figure out how to make passprops work. I'm trying to pass two variables, LRA and email to the next scene, but I keep getting undefined. I'm very new to this so I'm sorry if this is an easy question. Here is my code so far, feel free to give me any other tips you see wrong with it!

DataEntry.js

  class DataEntry extends Component {
    constructor(props) {
      super(props);
        this.state = {
          emailString: 'default@gmail.com',
          isLoading: false,
          message: '',
        mailerror: false,
        lraerror: false
        };
    }

  onEmailTextChanged(event) {
    this.setState({ emailString: event.nativeEvent.text });
    if (!validateEmail(this.state.emailString)){
      this.emailError = "Please enter a valid email"
      this.setState({error: true})
    }
    else{
      this.emailError = ""
      this.setState({error: false})
    }
    }

  onLRATextChanged(event) {
    this.setState({ LRAString: event.nativeEvent.text });
    if (!isValidID(this.state.LRAString)){
      this.LRAError = "Valid LRA ID is 4-10 alphanumeric characters"
      this.setState({error: true})
    }
    else{
      this.LRAError = ""
      this.setState({error: false})
    }
  }

  gotoNext() {  
    var emailtext = this.state.emailString
    var LRAtext = this.state.LRAString
    console.log(emailtext)
    this.props.navigator.push({
        id: 'PasswordView',
        name: 'Generated Password',
        email: emailtext,
        LRA: LRAtext
    });
  }

  renderScene(route, navigator) {
    var email = this.state.emailString
    var LRA = this.state.LRAString
    return (    
      <View style={styles.container}>
            <Text style={styles.description}>
                Please enter the email and LRA
            </Text>

            <View style={styles.flowRight}>
              <TextInput
                style={styles.searchInput}
                value={this.state.emailString}
                onChange={this.onEmailTextChanged.bind(this)}
                placeholder='Enter Email'/>
            </View>

            <Text style={styles.error}>
              {this.emailError}
            </Text>

            <View style={styles.flowRight}>
              <TextInput
                style={styles.searchInput}
                value={this.state.LRAString}
                onChange={this.onLRATextChanged.bind(this)}
                placeholder='Enter LRA ID'/>
            </View>

            <Text style={styles.error}>
              {this.LRAError}
            </Text>


            <TouchableHighlight style={styles.button}
                underlayColor='#99d9f4'
                onPress={this.gotoNext.bind(this)}>
               <Text style={styles.buttonText}>Retrieve Password</Text>
            </TouchableHighlight>
        <Text style={styles.description}>{this.state.message}</Text>
      </View>
    );
  }
render() {
        return (
          <Navigator
          renderScene={this.renderScene.bind(this)}
          navigator={this.props.navigator}
          navigationBar={
            <Navigator.NavigationBar style={{backgroundColor: '#48BBEC', alignItems: 'center'}}
                routeMapper={NavigationBarRouteMapper} />
          } />
        );
      }  
}

var NavigationBarRouteMapper = {
  LeftButton(route, navigator, index, navState) {
    return null;
  },
  RightButton(route, navigator, index, navState) {
    return null;
  },
  Title(route, navigator, index, navState) {
    return (
      <TouchableOpacity style={{flex: 1, justifyContent: 'center'}}>
        <Text style={{color: 'white', margin: 10, fontSize: 16}}>
          Data Entry
        </Text>
      </TouchableOpacity>
    );
  }
};


module.exports = DataEntry;

回答1:


You probably need to separate your Navigator into its own component, then you can assign the properties you need on the navigator as needed (in this case, the ...route.passProps spread operator being the property setting up passProps for use by the navigator).

I've set up the project with your code at https://rnplay.org/apps/V_EhdA.

Below is the code I used to get it working.

'use strict';

var React = require('react-native');
var {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  TouchableOpacity,
  TextInput,
  Navigator,
  TouchableHighlight
} = React;

function isValidID(string) {
    return true
}

var Two = React.createClass({
    render(){
    return(
        <View style={{marginTop:100}}>
          <Text style={{fontSize:20}}>Hello From second component</Text>
          <Text>id: {this.props.id}</Text>
          <Text>name: {this.props.name}</Text>
        </View>
    )
  } 
})

var Main = React.createClass ({

    getInitialState() {
        return {
          emailString: 'default@gmail.com',
          isLoading: false,
          message: '',
          mailerror: false,
          lraerror: false
      }
    }, 

  onEmailTextChanged(event) {
    this.setState({ emailString: event.nativeEvent.text });
    if (!validateEmail(this.state.emailString)){
      this.emailError = "Please enter a valid email"
      this.setState({error: true})
    }
    else{
        this.emailError = ""
        this.setState({error: false})
      }
    },

  onLRATextChanged(event) {
    this.setState({ LRAString: event.nativeEvent.text });
    if (!isValidID(this.state.LRAString)){
      this.LRAError = "Valid LRA ID is 4-10 alphanumeric characters"
      this.setState({error: true})
    }
    else{
      this.LRAError = ""
      this.setState({error: false})
    }
  },

  gotoNext() {  
    var emailtext = this.state.emailString
    var LRAtext = this.state.LRAString
    this.props.navigator.push({
        passProps: {
            id: 'PasswordView',
            name: 'Generated Password',
            email: this.state.emailstring,
            LRA: LRAtext,
        },
        component: Two
    });
  },

    render() {
      var email = this.state.emailString
      var LRA = this.state.LRAString
      return (
        <View style={styles.container}>
            <Text style={styles.description}>
                Please enter the email and LRA
            </Text>

            <View >
              <TextInput
                style={{height:40}}
                value={this.state.emailString}
                onChange={this.onEmailTextChanged.bind(this)}
                placeholder='Enter Email'/>
            </View>

            <Text >
              {this.emailError}
            </Text>

            <View >
              <TextInput
                style={{height:40}}
                value={this.state.LRAString}
                onChange={this.onLRATextChanged.bind(this)}
                placeholder='Enter LRA ID'/>
            </View>

            <Text>
              {this.LRAError}
            </Text>

            <TouchableHighlight style={{padding:30}}
                underlayColor='#99d9f4'
                onPress={ () => this.gotoNext() }>
               <Text>Retrieve Password</Text>
            </TouchableHighlight>

        <Text >{this.state.message}</Text>
      </View>
    );
}
})

class DataEntry extends React.Component {
    constructor(props) {
      super(props);
    } 
        render() {
        return (
          <Navigator
          configureScene={() => {
                      return Navigator.SceneConfigs.FloatFromRight;
                  }}
          initialRoute={{name: 'ComponentName', component: Main, index: 0}}
          renderScene={(route, navigator) =>    {
            if (route.component) {
                          return React.createElement(route.component, { ...this.props, ...route.passProps, navigator, route } );
                      }
        }}

          navigationBar={
            <Navigator.NavigationBar 
            style={{backgroundColor: '#48BBEC', alignItems: 'center'}}
                routeMapper={NavigationBarRouteMapper} />
          } />
        );
      }  
}

var NavigationBarRouteMapper = {
  LeftButton(route, navigator, index, navState) {
    if(index > 0) {
      return (
      <TouchableHighlight  style={{marginTop: 10}} onPress={() => {
            if (index > 0) {
              navigator.pop();
            } 
        }}>
       <Text>Back</Text>
     </TouchableHighlight>
 )} else {
 return null}
 },
  RightButton(route, navigator, index, navState) {
    return null;
  },
  Title(route, navigator, index, navState) {
    return (
      <TouchableOpacity style={{flex: 1, justifyContent: 'center'}}>
        <Text style={{color: 'white', margin: 10, fontSize: 16}}>
          Data Entry
        </Text>
      </TouchableOpacity>
    );
  }
};

var styles = StyleSheet.create({
    container: {flex:1},
    description: {flex:1}
})

AppRegistry.registerComponent('DataEntry', () => DataEntry);



回答2:


I'm not that experienced with React Native yet, so this might not be the best practice but I ended up with

renderScene: function(route, navigator) {
  return (
    <route.component route={route} navigator={navigator} />
  );
}

Where route.component can be any of your Screens (main Views).

And then setting state on the Navigator itself, since it has its own state and it is now passed as a prop to every View:

this.props.navigator.setState({isLoading: true});

To some extent it is an High Order Component.



来源:https://stackoverflow.com/questions/33763709/passprops-equivalent-for-navigator

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!