Reputation: 2381
I'm trying to create a reusable component in react native. The idea is to have only one component responsible to edit all the fields that I have.
Main Component
...
constructor(props) {
super(props);
this.state.FirstName = 'Joe'
}
...
const { FirstName } = this.state.FirstName;
<TouchableOpacity
onPress={() =>
NavigationService.navigate('EditData', {
label: 'First Name',
initialValue: FirstName,
onSubmit: (FirstName) => this.setState({ FirstName })
})
}
>
<CardItem>
<Left>
<FontAwesome5 name="user-edit" />
<Text>First Name</Text>
</Left>
<Right>
<Row>
<Text style={styles.valueText}>{FirstName} </Text>
<Icon name="arrow-forward" />
</Row>
</Right>
</CardItem>
</TouchableOpacity>
// Keep doing the same for other fields
Then, the edit component should be reusable.
constructor(props) {
super(props);
// callback function
this.onSubmit = props.navigation.getParam('onSubmit');
// label/value
this.state = {
label: props.navigation.getParam('label'),
value: props.navigation.getParam('initialValue')
};
}
render() {
const { onSubmit } = this;
const { label, value } = this.state;
return (
<Container>
<Header />
<Content>
<Item floatingLabel style={{ marginTop: 10 }}>
<Label>{label}</Label>
<Input
value={value}
onChangeText={val => this.setState({ value: val })}
/>
</Item>
<Button
onPress={() => {
onSubmit(value);
NavigationService.navigate('TenantDetails');
}
}
>
<Text>OK</Text>
</Button>
</Content>
</Container>
);
}
When back to the main component, the first name value was not changed.
My NavigationService in case it might be the problem:
import { NavigationActions } from 'react-navigation';
let _navigator;
function setTopLevelNavigator(navigatorRef) {
_navigator = navigatorRef;
}
function navigate(routeName, params) {
_navigator.dispatch(
NavigationActions.navigate({
routeName,
params,
})
);
}
// add other navigation functions that you need and export them
export default {
navigate,
setTopLevelNavigator,
};
Thanks
Upvotes: 1
Views: 148
Reputation: 1015
You could pass a callback to your new component which handles this. The new component would start with a state with the initialValue set. It looks like you might be using react-navigation
so I would recommend that if you want this component on its own screen you could do
this.navigation.navigate('SetValueScreen', {
initialValue: this.state.email,
onSubmit: (email) => this.setState({ email })
})
and on the SetValueScreen get the initialValue in the constructor and in the render use the callback
class SetValueScreen extends React.PureComponent{
constructor(props){
super(props)
this.onSubmit = props.navigation.getParam('onSubmit');
this.state = {
value: props.navigation.getParam('initialValue')
}
}
render(){
const { onSubmit } = this
const { value } = this.state
return (
...
<Right>
<TextInput value={value} onChangeText={(value) => setState({ value })} />
</Right>
<Button onPress={() => {
onSubmit(value)
navigation.goBack()
}} >
OK
</Button>
...
)
}
}
I hope this helps.
Upvotes: 1