Reputation: 842
I am working on the profile picture for my app for which I have designed a custom reusable component called ProfilePhoto
. I am using that component in the Profile
parent screen as seen below in my code.
Initially, no profile picture is selected from the gallery and nothing renders, which is fine. But after I have selected an image from the gallery (to prove that I log the path) it's not appearing in the component as expected.
My code:
//Parent - Profile Screen
class ProfileScreen extends Component {
constructor(props) {
super(props);
console.log('PROFILE SCREEN');
console.log(auth().currentUser);
this.state = {
image: {
uri: null, //' '
width: null,
height: null,
mime: null,
},
};
}
renderImage(image) {
return <ProfilePhoto diameter={228} borderWidth={5} image={image} />; //Custom Component
}
pickSingleWithCamera(cropping, mediaType = 'photo') {
ImagePicker.openPicker({
cropping: cropping,
width: 228,
height: 228,
includeExif: true,
mediaType,
cropperCircleOverlay: true,
})
.then(image => {
console.log('received image', image);
console.log('image path: ', image.path);
this.setState({
image: {
uri: image.path,
width: image.width,
height: image.height,
mime: image.mime,
},
images: null,
});
})
.then(async () => {
console.log('Uploading...');
this.uploadImage(this.state.image.uri);
})
.catch(e => alert(e));
}
render() {
return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<ScrollView>
<Text>Profile Screen</Text>
<View>
{this.state.image ? this.renderImage(this.state.image) : null}
</View>
<Button
title="Pick Image"
onPress={() => this.pickSingleWithCamera(true)}
/>
</ScrollView>
</View>
);
}
}
export default ProfileScreen;
//Custom Component - ProfilePhoto
class ProfilePhoto extends Component {
constructor(props) {
super(props);
this.diameter = this.props.diameter;
this.borderWidth = this.props.borderWidth;
this.image = this.props.image || null;
console.log('image: ', this.image);
}
render() {
return (
<View
style={{
width: this.diameter,
height: this.diameter,
borderRadius: this.diameter / 2,
borderWidth: this.borderWidth,
borderColor: '#00A1ED',
shadowColor: '#00A1ED67',
shadowOffset: {width: 0, height: 7},
shadowRadius: 6,
}}>
<Image
source={this.image}
style={{
width: this.diameter,
height: this.diameter,
borderRadius: this.diameter / 2,
}}
/>
</View>
);
}
}
export default ProfilePhoto;
My logs:
//Initial Log
image: {"height": null, "mime": null, "uri": null, "width": null}
//After Picking image
image: {"height": 228, "mime": "image/jpeg", "uri": "file:///storage/emulated/0/Pictures/e56f5507-3e45-409d-990f-c88812ff2c4b.jpg", "width": 228}
Help would be very much appreciated.
Upvotes: 1
Views: 492
Reputation: 1731
Should be this.renderImage(this.state.image.uri)
instead of this.renderImage(this.state.image)
?
The source
part of the RN <Image/>
tag should be a uri instead of an object.
After changing the stuff mentioned above, this.props.image
in your your ProfilePhoto Component should be a uri that can be null
or a string
. Now try:
<Image
source={this.props.image? this.props.image : null}
style={{
width: this.diameter,
height: this.diameter,
borderRadius: this.diameter / 2,
}}
/>
and remove this.image = this.props.image || null;
in the constructor
Update: Glad it works, updating the reason here for easier reading to any potential reader
The reason is that this.props.image
is re-assigned to a local variable this.image
, since the UI is depended on this.image
, which is not state
/ props
, it won't reflect to any changes of the image source
Upvotes: 2