I have a large long image with a few inputs at the bottom in my react native view. When the view loads I want it to be "scrolled" to the bottom of the page -- all the examples I can find online are triggered because of some event that the user does.
I want to call scrollToEnd() but I'm not sure where in the lifecycle the ref will actually be set -- anyone have ideas?
Use scrollToEnd this way. It will take to the bottom of ScrollView
<ScrollView
ref={ref => this.scrollView = ref}
onContentSizeChange={(contentWidth, contentHeight)=>{
this.scrollView.scrollToEnd({animated: true});
}}>
I am not clear with your question but
With react-native Image component we have onLoad prop. I think this is what you are looking for.
try something like:
<Image source={{uri...}} onLoad={(e)=>this.handleImageLoaded(e)}/>
then inside handleImageLoaded method you can use scrollToEnd() with some ref as per your code.
also there are other useful props like onLoadStart/End check here
https://facebook.github.io/react-native/docs/image
Or if you are just waiting for the view to render then to scroll
for that I think componentDidAppear() lifecycle method, if using react-native -navigation by wix
or with react-navigation
willFocus, willBlur, didFocus and didBlur events for the component render cycle.. explained here
https://reactnavigation.org/docs/en/navigation-prop.html#addlistener-subscribe-to-updates-to-navigation-lifecycle
when its changed source of any image in component there is blinking occurs which I try to avoid.
To do so I searched and decided to use ref(direct manipulation)
but it doenst change anything, so I use traditional way, changing url property in the state, it works but blink occurs.
Changing image source, fired when image started to move;("onPanResponderStart") function. here is code;
onPanResponderStart:(e, gesture)=>{
//not change image!
// this.refs['refTabure'].setNativeProps({
// source: require('../newImage.png')
// });
//it works, but blink occurs
this.setState({tabureSagImageUrl:require('../newImage.png')})
},
...
return (
<View style={styles.TabureStyle}>
<Animated.Image ref="refTabure" style={[panStyle, styles[this.props.Name], {opacity:this.state.opacity}]}
{...this.panResponder.panHandlers}
source={this.state.tabureSagImageUrl}>
</Animated.Image>
</View>
);
how can I edit the source of image without rerendering component that cause blinking ?
I am using https://github.com/jacklam718/react-native-dialog-component for my Dialogs and I am having some problems with async functions not refreshing the dialog. I am using it like in the example with
render() {
return (
...
<Button onItemPressed={(item) => {
this.completeMovementDialog.show()
}}/>}
...
<CompleteMovementDialog onRefresh={() => this.getStationsNearToPlayer()}
ref={(completeMovementDialog) => {
this.completeMovementDialog = completeMovementDialog;
}}/>
The CompleteMovementDialog uses the onRefresh Method in componentDidMount() and is a wrapper for a DialogComponent. It works fine, when i refresh the list, that is retrieved from the backend by this.getStationsNearToPlayer(). The problem is, that the CompleteMovementDialog component gets loaded, as soon as the component around it gets loaded. So when i call this.startMovementDialog.show() it does not go into componentDidMount anymore and the list is never refreshed unless you refresh it manually. Does anybody have a tip, how i can achieve to forecefully refresh the list before show()? Or is there a better library to show dialogs? I heard ref is not a good practice...
For somebody stumbling across this:
The DialogComponent offers a onShown and onDismissed property, where you can pass a function, that can be an api call. I solved it by loading the data in the onShown callback and set the view to loading mode again, when the dialog was dismissed and the onDismissed callback occured.
I experience a behaviour where TouchableHighlight and TouchableOpacity reacts visually upon render (onPress is not being called).
One thing is that it looks just a little strange, when I enter the page and my button make a small "blink". This is strange but tolerable. The more frustrating part is that if I alter state for the parent component and thus invoke a re-render(), the button will "blink" again, making all buttons blink whenever I alter state.
Pushing the buttons alters page state, and thus pushing a button makes both buttons "blink".
I use react-redux, but this should not affect this behaviour.
The code below is just for illustration.
render()
{
return(
<View>
<ToucableHightlight> //Click here changes state
<Content/>
</ToucableHightlight>
<ToucableHightlight> //Click here changes state
<Content/>
</ToucableHightlight>
<View>
);
}
Add activeOpacity in TouchableOpacity and it will force to not blink.
<TouchableOpacity style={styles.opecity} activeOpacity={1}>
I solved the problem. Earlier during my render function i defined the "Content"-components, resulting in new (but alike) components being defined during each update. Placing the definitions of "Content" outside of the render function fixed it, so that the components no longer flashes when the page is re-rendered.
This explains why my component was rendered as a new component upon each render in the parent component, but it does not explain why a TouchableHighlight blinks during its initial render.
Buttons blinking during initial render is acceptable to me - buttons blinking upon any state-change is not.
So I am sufficiently happy now.
Not sure if it's because I'm running a later version, but I found this blinking behavior happens only on the first click.
My solution was putting the code that triggers rerendering in a setTimeout
<TouchableOpacity
onPress={function() {
setTimeout(function() {
_this.setState({myState: 'someValue'})
});
}}
>
What does this mean?
This happens when I update a list of iterated views something like
<View style={{ flexDirection: 'row', padding: 20, backgroundColor: '#fff' }}>
<Ionicons name={jobIcon} color={theme.iconColor} size={30} />
<Text>{jobService}</Text>
<Text>{jobDate}</Text>
</View>
mapped inside a scrollview.
this error pops up when I modify the array from child scene.
scene1 - is where the ScrollView with job list array of views
sence2 - is where I delete a job and should update scene1 when I do remove a job
If you want the LayoutAnimation to work with ScrollView, replace
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut)
with
LayoutAnimation.configureNext({
duration: 300,
create:
{
type: LayoutAnimation.Types.easeInEaseOut,
property: LayoutAnimation.Properties.opacity,
},
update:
{
type: LayoutAnimation.Types.easeInEaseOut,
}
});
This works on both Android and iOS without any crashes.
In my case I was using LayoutAnimation for my ScrollView. Inside it a map of Items. When an Item is removed from the list this happens. Not using LayoutAnimation seems to be working fine.
It's happening when you call layout animation when it already in process. iOS will show an warning while Android will explode with this error.
You can use this easy pattern to fix it when you're using LayoutAnimation from same component.
layoutAnimation() {
if (!this.layoutAnimationActive) {
this.layoutAnimationActive = true;
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInOut, () => { this.layoutAnimationActive = false; });
}
}
This happens when a component only has x amount of children, but you are trying to remove a child with index greater than x. Like an index out of bounds exception that is common with arrays. Can cause lots of frustration because often times the child you are trying to remove DOES INFACT EXIST. But might be happening because you are using a third party component that only expects a certain amount of children.
For me, it happened when I put an extra child into air-bnb MapView. I fixed the issue by making this element the child of it's grandparent (it was absolutely positioned so it didn't affect styling).
I encountered this issue when creating a react-native application using Expo.
This error was often getting raised when I was rendering new Markers onto a Map (which was rendered via a MapView component).
What fixed the issue for me was to add a key prop to the Marker component e.g.
<Marker coordinate={coordinate} key={`${coordinate.latitude}_${coordinate.longitude}`} />
Hope this helps anyone who also encounters this issue when dealing with MapView and Marker components!
In my case, I was deleting an item in a virtualized list. I was using redux to manage the data of the list and updated the list with the new data. However, the component for the item that was deleted caused this error.
I solved this by adding a boolean state property on this item component, example "hideItem". My item was a class component but a setState hook could also be used for a functional component. I set this to true after deletion. The post hid with layout animation correctly, and when the page refreshed it no longer rendered the deleted item. Hence, the error went away on android without needing to not use LayoutAnimation.
Evidently, it seems this bug can show its ugly face in various conditions. After a couple of hours of debugging, I found my root cause to be a key prop being passed to a component that didn't require it. I'm still unsure of why this was causing a crash, however, I suspect it has to do with the fact that the component accepts the key as a unique way to identify the view, but was also using the componentWillReceiveProps(props: *) lifecycle method that updated the component's state.
This is likely to happen if you're using some native components, where some ViewManager returns a LayoutShadowNode in createShadowNodeInstance of ViewGroupManager or something extending ReactShadowNode in createShadowNodeInstance of ViewManager on Android, and a RCTShadowView in the shadowView method of RCTViewManager on iOS. But, returns null/nil for some other View in some other ViewManager.
Then, if you combine children of both types in the same parent, and any of the elements without shadowViews/Nodes come before the changing number of elements which do have shadowViews/Nodes, then the indices won't match up, and the RCTUIManager on iOS and NativeViewHierarchyManager on Android will choke and produce these exceptions.
I solved a similar issue in react-native-svg recently, by making all the ViewManagers return values rather than null/nil. https://github.com/facebook/react-native/issues/23350
So, try upgrading react-native-svg to v9.2.4 and the issue might be fixed. Or, try moving the IonIcons to the end of your children.
I had the same issue, because I had an Array.map inside a condition which I was updating using LayoutAnimation.
I fixed it by moving the state variable inside the map function.
I am using vitalized flatlist with swipe left right delete option, and when list is more than 200 items and I use LayoutAnimation then the above problem comes out on arbitrary based, I figured out that deleted item still exist because of LayoutAnimation so you can play around with timings of update using the following code
LayoutAnimation.configureNext({
duration: 300,
create:
{
duration:500
type: LayoutAnimation.Types.easeInEaseOut,
property: LayoutAnimation.Properties.opacity,
},
update:
{
duration: 500,
type: LayoutAnimation.Types.easeInEaseOut,
}
});
this.refs['task'].setNativeProps({
style: {transform: [{translateX: Dimensions.get('window').width}]},
});
one more thing, I am also hiding the item suddenly after it's deletion occurs
here is code snippet
this.props.handleDeleteTask(this.props.item.id);
this.setState({hideItem:true}) // here I am hiding through state function, so the item should disappear right after it's deletion.