如何在react-native中将读写数据源项从父视图传递给子视图?

时间:2016-02-19 21:06:37

标签: listview datasource react-native

使用react-native,父视图如何将读写对象传递给子视图,在哪里可以修改,然后在子视图返回到父视图时重新呈现父视图?

我在导航器中有一个WaypointList ListView。 当用户选择一行时,DetailView会显示TextInput以进行编辑。



// The Parent "Master View"
var WaypointList = React.createClass({

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

    return {
      itemList: this._genRows(),
      dataSource: ds.cloneWithRows(this._genRows()),
      editEnabled: false,
      planLocked: false,
      selectionCount: 0,
      unitType: 0,
    };
  },

  // ToDo: Turn this into a real database datasource
  _genRows: function(): Array < any > {
    var arrayList = [];
    var waypoint = new Waypoint('Waypoint1', 0.0, 0.0, 10, true);
    arrayList.push(waypoint);
    waypoint = new Waypoint('Waypoint2', 20.0, 4.0, 10, true);
    arrayList.push(waypoint);
    return arrayList;
  },

  getDataSource: function(waypoints: Array < any > ): ListView.DataSource {
    return this.state.dataSource.cloneWithRows(waypoints);
  },

  selectRow: function(waypoint: Object) {
    this.props.navigator.push({
      title: waypoint.name,
      component: WaypointScreen,
      passProps: {
        waypoint: waypoint,
      },
    });
  },
});

// The Child "Detail View"
// How can I modify an object passed into the "Detail View"
// passProps appears to be read-only ?
var DetailView = React.createClass({

      textInputValue: null,

      getInitialState: function() {
        console.log('name:', this.props.person.name);
        console.log('age:', this.props.person.age);
        return {
          textDistance: this.props.waypoint.distance.meters.toString(),
          textDepth: this.props.waypoint.depth.meters.toString(),
        };
      },

      render: function() {
          return ( < View style = {
                {
                  flexDirection: 'row',
                  justifyContent: 'center'
                }
              } >
              < TextInput style = {
                styles.textInput
              }
              ref = 'distance1'
              placeholder = "Enter meters"
              editable = {
                isEditable
              }
              keyboardType = "decimal-pad"
              returnKeyType = 'next'
              onChangeText = {
                (text) => {
                  text = text.replace(/\D/g, '');
                  var meters = parseFloat(text);
                  this.setState({
                    textDistance: text
                  });
                }
              }
              value = {
                this.state.textDistance
              }
              onSubmitEditing = {
                (event) => {
                  this.refs.depth1.focus();
                }
              }
              />

      <View style={styles.separatorHorizontal} / >
              < /View>

    );
  },
});
&#13;
&#13;
&#13;

我在两周前开始学习反应原生语,但我并没有找到解决方案。

passProps仅用于只读信息吗?

如何实现数据源的读写修改?

提前致谢。

非常感谢任何提示或方向,

-Ed

1 个答案:

答案 0 :(得分:1)

您需要在父级中设置状态,并将该状态作为道具传递给子级。当子元素更改为您需要的新值时,您将为父级设置一个回调函数,该父级重置父状态,而父状态又会重置使用该值的任何子级的道具。

查看this非常基本的例子:

https://rnplay.org/apps/huQTKA

'use strict';

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

var Parent = React.createClass({

  getInitialState() {
        return { text: '' }
    },

  onChange(text){
    this.setState({ text })
  },

  render() {
    return (
      <View style={styles.container}>
        <Text>Hello, { this.state.text }</Text>
        <Child text={ this.state.text } onChange={ this.onChange } />
     </View>
    );
  }
});       

var Child = React.createClass({
  render() {
    return (
      <View style={styles.container2}>
        <TextInput onChangeText={ (text) => this.props.onChange(text) } style={ styles.textInput }  />
        <Text>{ this.props.text }</Text>
      </View>
    );
  }
});

var styles = StyleSheet.create({
  container: {
    flex: 1,
    marginTop:50
  },
  container2: {
    marginTop:25
  },
  textInput: {
    height: 60,
    backgroundColor: '#efefef',
    borderBottomWidth: 1,
    borderBottomColor: '#ededed',
    marginTop:13,
    marginBottom:13
  }
});

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