I am doing an animation in which i use a video(I am using react-native-video). There is a bunch of animations going on and in certain point i would like to play video. So far, I did set up setTimout method in render() like this: "setTimeout(() => {this.setState({paused: false})}, 5000)" and it works in the beginning but when i quit the animation to parent view then I keep receiving warnings about updating unmounted component. Is there another way of starting a video in a given time?
Cheers,
misi06
It's a bad practice to add setState in the render method. Add it in the componentWillMount or componentWillReceiveProps based on situation.
Related
I have a component that is sometimes pushed as a regular screen on top of the stack, and sometimes shown as a modal.
When a specific event occurs, I need to get rid of the component. But I don't know if it's a modal or a regular screen, so I don't know if I need to call Navigation.pop(componentId) or Navigation.dismissModal(componentId). Is there a way to check before calling?
I tried just calling both in succession, but then one of them fails and throws an error.
I could wrap them both in a try/catch, but that seems like an anti-pattern. What is the recommended way to deal with this?
You can use a command listener and track when it's pushed or shown as a modal
I have a sort of WhatsApp clone project. From the users listing component, it will redirect to each users chatWindow. I dont want to re-render the chatWindow component which was already rendered.
This is what happening
Navigate to ChatWindow1 from Userchannel - ChatWindow1 mounted
Navigate to Userchannel from ChatWindow1 - ChatWindow1 unmounted
Navigate to ChatWindow2 from Userchannel - ChatWindow2 mounted
Navigate to Userchannel from ChatWindow2 - ChatWindow2 unmounted
Navigate to ChatWindow1 from Userchannel - ChatWindow1 mounted again.
I know using state we can render the ChatWindow again. But Is there a possibility to avoid the unwanted re-renderng. Currently I am usinf RNRF as the router.
Optimising re-render can be done in multiple ways in react.
You can use PureComponent Implementation where react itself shallow compares the props and re-renders only when necessary.
If you want more granular control, go with shouldComponentUpdate which gives you a lifecycle method where you can compare the props and decide whether you want to avoid render. Please make sure the comparison is not complex. The more complex comparisons can make the app slow, in which case the optimisation back fires.
Use Flat list instead of List view or scrollview for better performance and make sure you add a keyExtractor and Item as a PureComponent.
Make sure the code splitting is properly done. you cannot optimise a very large amount code in a single page. If the components are small enough, you can optimise them better.
If you have a lot going on the JS, I would strongly recommend using a native navigation solution like react-native navigation
You can use console logs in render to find out the render count and take necessary actions. Please make sure that these optimisations can block necessary renders as well. So make sure props are different when you want to re-render things.
Regarding the mount / unmount
In most cases the navigation keeps the screens in the stack. Going back will not trigger a re-render. You can do one thing, make sure page works on props, so that re-render happens only when data changes.
Helpful Links:
https://medium.com/#ohansemmanuel/how-to-eliminate-react-performance-issues-a16a250c0f27
https://medium.com/vena-engineering/optimizing-react-rendering-61a10e741edb
Since your screens are unmounted there is nothing wrong to re-render when you navigate back to that screen. Of course you could avoid this by having all your screens mounted but that might cause memory leak.
Currently, I read some state from AsyncStorage in componentWillMount. However, some screens modify what is in AsyncStorage, and it does not appear that componentWillMount is called when returning (this.props.navigation.goBack()) to a screen, so they don't receive the update.
What, if anything, is called? What are the component lifecyle functions that are called on the return to a screen? Are any of these only called once, when the screen is to be shown again?
componentDidFocus is currently in design not avaiable yet, see react-native open issue #51.
Try this alternative way react-navigation-addons.
I built an alphabet scrubber that scrolls a SectionList. The SectionList is optimized through the use of getItemLayout. If I scrub over the alphabet, the scrolling happens as planned, but the SectionList does not rerender until I release my finger from the screen.
See this expo snack
Anyone ideas on how to solve this?
Solved it by going through the source code of PanResponder. PanResponder sets an interaction handle through the InteractionManager. You can access this handle through this.panResponder.getInteractionHandle() (undocumented feature), and then clear it everytime you scroll to a location in the SectionList:
if (this.panResponder.getInteractionHandle()) {
InteractionManager.clearInteractionHandle(
this.panResponder.getInteractionHandle()
);
}
This will move the SectionList up in the queue for doing its visibility calculations and renders.
I advice to heavily optimize this by clearing the interaction handle as few times as possible, since the InteractionManager is used for performance reasons.
For the sectionList to update dynamically you need to place the data its using into State. This Expo example(done by someone else), is a good example:
https://snack.expo.io/Syy1bqKxW
His panResponder has all its data in state and on every "handlePanResponderMove" he calls setState() to update the position every time it moves. All in all, if your data is not in state, it will not update dynamically for you. Placing your data into state in React-Native is how it keeps track of your data changes dynamically.
Hope this helps!
I would like to know how to implement a component that has a fixed layout, but frequently updates its display.
Suppose it is an element that needs to be tied to some in app state like a stop watch timer:
(source: mzstatic.com)
If the timer is running then the hundredths of seconds should be ticking on every frame. But in react native my instinct is to make that a <Text>00:12.36</Text> element.
Obviously calling render() is wrong. Is creating a native module the only option for this? Or is there some mechanism to drive frequent display changes within pure js? Are there best practices in this case?
Checkout setNativeProps it allows directly set text (and other properties of elements). Here're docs
You will be able to set text of <Text> component as
this._textInput.setNativeProps({text: '00:12:36'});