Подтвердить что ты не робот

Изменить свойства Native Pass на всплывающем навигаторе

Я использую NavigatorIOS для своего родного приложения. Я хочу передать некоторые свойства при навигации по предыдущему маршруту.

Пример: Я нахожусь на странице формы. После отправки данных я хочу вернуться к предыдущему маршруту и ​​сделать что-то на основе представленных данных

Как мне это сделать?

4b9b3361

Ответ 1

Не могли бы вы передать функцию обратного вызова в навигационных реквизитах, когда вы нажимаете новый маршрут, и вызываете это с данными формы перед тем, как перейти к предыдущему маршруту?

Ответ 2

Пример кода, показывающий, как использовать обратный вызов перед попсом. Это специально для Navigator, а не NavigatorIOS, но для этого может быть применен аналогичный код.

У вас есть Page1 и Page2. Вы переходите с Страница1 на страницу2, а затем возвращаетесь на страницу. Вам нужно передать функцию обратного вызова из Page2, которая запускает некоторый код в Page1, и только после этого вы вернетесь к странице.

В Page1 -

_goToPage2: function() {
  this.props.navigator.push({
    component: Page2,
    sceneConfig: Navigator.SceneConfigs.FloatFromBottom,
    title: 'hey',
    callback: this.callbackFunction,
  })
},

callbackFunction: function(args) {
  //do something
  console.log(args)
},

В Page2 -

_backToPage1: function() {
  this.props.route.callback(args);
  this.props.navigator.pop();
},

Функция "callbackFunction" будет вызвана до "pop". Для NavigatorIOS вы должны сделать тот же обратный вызов в "passProps". Вы также можете передать аргументы этому обратному вызову. Надеюсь, что это поможет.

Ответ 3

Вы можете использовать AsyncStorage, сохранить некоторое значение для дочернего компонента, а затем вызвать navigator.pop():

AsyncStorage.setItem('postsReload','true');
this.props.navigator.pop();

В родительском компоненте вы можете прочитать его из AsyncStorage:

async componentWillReceiveProps(nextProps) {
    const reload =  await AsyncStorage.getItem('postsReload');
    if (reload && reload=='true')
    {
       AsyncStorage.setItem('postsReload','false');
       //do something
    }
  }

Ответ 4

Для NavigatorIOS вы также можете использовать replacePreviousAndPop().

код:

'use strict';

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

var MainApp = React.createClass({
  render: function() {
    return (
      <NavigatorIOS
          style={styles.mainContainer}
          initialRoute={{                   
            component: FirstScreen,
            title: 'First Screen',
            passProps: { text: ' ...' },
        }}
      />
    );
  },
});

var FirstScreen = React.createClass({
  render: function() {
    return (
      <View style={styles.container}>
        <Text style={styles.helloText}>
              Hello {this.props.text}
        </Text>
        <TouchableOpacity 
            style={styles.changeButton} onPress={this.gotoSecondScreen}>
            <Text>Click to change</Text>
        </TouchableOpacity>      
      </View>
    );
  },
  gotoSecondScreen: function() {
        console.log("button pressed");
    this.props.navigator.push({
        title: "Second Screen",
      component: SecondScreen
    });
    },
});

var SecondScreen = React.createClass({
  render: function() {    
    return (
      <View style={styles.container}>
        <Text style={styles.helloText}>
          Select a greeting
        </Text>
        <TouchableOpacity 
            style={styles.changeButton} onPress={() => this.sayHello("World!")}>
            <Text>...World!</Text>
        </TouchableOpacity>
        <TouchableOpacity 
            style={styles.changeButton} onPress={() => this.sayHello("my Friend!")}>
            <Text>...my Friend!</Text>
        </TouchableOpacity>   
      </View>
    );
  },
  sayHello: function(greeting) {
        console.log("world button pressed");
    this.props.navigator.replacePreviousAndPop({
        title: "First Screen",
      component: FirstScreen,
      passProps: {text: greeting}
    });
    }
});


var styles = StyleSheet.create({
  mainContainer: {
        flex: 1,
        backgroundColor: "#eee"
  },
  container: {
    flex: 1,
    alignItems: "center",
    justifyContent: "center",
    marginTop: 50,    
  },
  helloText: {
    fontSize: 16,
  },
  changeButton: {
    padding: 5,
    borderWidth: 1,
    borderColor: "blue",
    borderRadius: 4,
    marginTop: 20
  }
});



AppRegistry.registerComponent("TestApp", () => MainApp);

Здесь вы можете найти рабочий пример: https://rnplay.org/apps/JPWaPQ

Я надеюсь, что это поможет!

Ответ 5

У меня была та же проблема с React Native navigator, которую мне удалось решить с помощью EventEmitters и Subscribables. Этот пример здесь был действительно полезен: https://colinramsay.co.uk/2015/07/04/react-native-eventemitters.html

Все, что мне нужно было сделать, это обновление для ES6 и последней версии React Native.

Верхний уровень приложения:

import React, { Component } from 'react';
import {AppRegistry} from 'react-native';
import {MyNavigator} from './components/MyNavigator';
import EventEmitter from 'EventEmitter';
import Subscribable from 'Subscribable';

class MyApp extends Component {
    constructor(props) {
        super(props);
    }
    componentWillMount() {
        this.eventEmitter = new EventEmitter();
    }
  render() {
    return (<MyNavigator events={this.eventEmitter}/>);
  }
}

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

В функции _renderScene вашего навигатора убедитесь, что вы включили поддержку "событий":

_renderScene(route, navigator) {
    var Component = route.component;
    return (
        <Component {...route.props} navigator={navigator} route={route} events={this.props.events} />
    );
}

И вот код для компонента FooScreen, который отображает список.

(Обратите внимание, что react-mixin использовался здесь, чтобы подписаться на событие. В большинстве случаев mixins следует избегать в пользу компонентов более высокого порядка, но в этом случае я не мог найти способ:

import React, { Component } from 'react';
import {
  StyleSheet,
  View,
  ListView,
  Text
} from 'react-native';
import {ListItemForFoo} from './ListItemForFoo';
import reactMixin from 'react-mixin'
import Subscribable from 'Subscribable';

export class FooScreen extends Component {
  constructor(props) {
    super(props);

    this._refreshData = this._refreshData.bind(this);
    this._renderRow = this._renderRow.bind(this);

    var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});

    this.state = {
      dataSource: ds.cloneWithRows([])
    }
  }

  componentDidMount(){
    //This is the code that listens for a "FooSaved" event.
    this.addListenerOn(this.props.events, 'FooSaved', this._refreshData);
    this._refreshData();
  }

  _refreshData(){
    this.setState({
      dataSource: this.state.dataSource.cloneWithRows(//YOUR DATASOURCE GOES HERE)
    })
  }
  _renderRow(rowData){
      return <ListItemForFoo 
          foo={rowData} 
          navigator={this.props.navigator} />;
  }
  render(){
    return(
      <ListView
      dataSource={this.state.dataSource}
      renderRow={this._renderRow}
      />
      )

  }
}
reactMixin(FooScreen.prototype, Subscribable.Mixin);

Наконец-то. Нам нужно фактически выпустить это событие после сохранения Foo:

В вашем компоненте NewFooForm.js у вас должен быть такой метод:

  _onPressButton(){
    //Some code that saves your Foo

     this.props.events.emit('FooSaved'); //emit the event
     this.props.navigator.pop();  //Pop back to your ListView component
  }