Reputation: 5459
Using react-native, how can a parent view, pass a read-write object to a child view, where it can be modified, then have the parent view re-render when the child returns to the parent view?
I have a WaypointList ListView in a navigator. When user selects a row, the DetailView displays TextInput's for editing.
// 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>
);
},
});
I started learning react-native about 2 weeks ago yet I am no closer to figuring out a solution.
Are passProps only for read-only information?
How can read-write modification of a datasource be achieved?
Thanks in advance.
Any tips or direction are much appreciated,
-Ed
Upvotes: 0
Views: 296
Reputation: 53711
You need to set the state in the parent, and pass that state down as props to the child. When the child element changes to the new value you need, you set a callback function to the parent that resets the parent state, which in turn resets the props of any children using that value.
Check out this very basic example:
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);
Upvotes: 1